diff -aruN shujit-0.2.5/ChangeLog shujit-0.2.6/ChangeLog --- shujit-0.2.5/ChangeLog Sun Jan 10 18:02:46 1999 +++ shujit-0.2.6/ChangeLog Thu Jan 21 19:43:44 1999 @@ -1,5 +1,63 @@ $Id$ +[19990121] + +pre-assembled code 中のラベル名のスペルミスを訂正。 + exc_hanlder_shift_done -> exc_handler_shift_done +(code.c) + +long 型の shift 命令 (lshl, lshr, lushr) で、 +`rorb $1,%cl' を `rorb %cl' とした。 +(code.c) + +iload_*, lload_* 命令で、 +`movl 0(%esi),...' を `movl (%esi),...' とした。 +(code.c) + +invokeJITCompiledMethod() (invoker.c) 中で、 +invoke{,Synchronized}JavaMethod() を呼び出す代わりに処理を書き下した。 +メソッド呼び出しの高速化。 +(invoker.c) + +invokeJITCompiledMethod() 中に profiling (java -prof) のための +時間計測コードを入れた。ただし、デフォルトでは無効化してある。 +マクロ ENABLE_PROFILING で有効に。 +(invoker.c) + +0.2.6 リリース。 + +[19990120] + +生成する native code の頭で行っていた native code のアドレスを求める処理 + nativecode = mb->CompiledCode +を、アドレスを必要とする各箇所 + exc_handler, ret, tableswitch, lookupswitch, new(rewrite) +に移した。局所変数 nativecode を削除。 +メソッド呼び出しの高速化。 +(code.c) + +例外発生時にスタックをクリアするために、スタックのベースを +native code の局所変数 ostack に保存していた。 +この ostack を削除し、例外発生時にアドレスを計算するようにした。 +(code.c) + +native code の局所変数のために 48バイト確保していたところ、 +最低限必要な 4バイトに減らした。 +(code.c) + +[19990118] + +class initializer はコンパイルしないようにした。 +(compiler.c) + +オプション cmplclinit を用意。 +class initializer をコンパイルする。 +(compiler.c, compiler.h) + +[19990117] + +0.2.5 リリース。 + [19990110] GNU bash, version 2.01.1(1)-release では、シェルスクリプト diff -aruN shujit-0.2.5/code.c shujit-0.2.6/code.c --- shujit-0.2.5/code.c Sun Jan 17 13:04:23 1999 +++ shujit-0.2.6/code.c Thu Jan 21 16:54:38 1999 @@ -21,6 +21,11 @@ #endif /* JITDO */ +#define COMPILEDCODE(DST) \ + __asm__("movl %0,%" #DST : : "m" (mb)); /* DST = mb */\ + METHOD_COMPILEDCODE(DST,DST); /* DST = mb->CompiledCode */ + + volatile void assembledCode( JHandle *o, struct methodblock *mb, int args_size, ExecEnv *ee #ifdef RUNTIME_DEBUG @@ -28,8 +33,6 @@ #endif ) { /* ee: 0x14(%ebp) */ - unsigned char *ostack; /* stack base */ /* -4(%ebp) */ - unsigned char *nativecode; /* for `ret' instruction */ /* -8(%ebp) */ int32_t bytepcoff; /* to handle exceptions */ /* %esi: stack_item *vars @@ -213,11 +216,13 @@ CODE_WITHOUT_DEBUG(opc_methodhead, head, STANY, STSTA) { __asm__("pushl %ebp\n\t" "movl %esp,%ebp\n\t" - "subl $48,%esp\n\t" /* 4 * #local_var */ + "subl $4,%esp\n\t" /* 4 * #local_var */ +#define SAVED_REG_AREA 16 /* 16 bytes: ecx,edx,edi,esi */ "pushl %ecx\n\t" "pushl %edx\n\t" "pushl %edi\n\t" "pushl %esi"); + #ifdef RUNTIME_DEBUG /* write class and method name */ if (runtime_debug) { @@ -256,12 +261,6 @@ __asm__("popl %eax"); } #endif - { - register unsigned char *esp asm("esp"); - ostack = esp; - } - - nativecode = mb->CompiledCode; /* %esi = ee->current_frame->vars */ { @@ -285,7 +284,7 @@ /* method tail */ CODE(opc_methodtail, tail, STANY, STSTA) { - __asm__("leal -64(%ebp),%esp"); + __asm__("leal -20(%ebp),%esp"); /* -4 * (#local_var + #registers_on_stack) */ __asm__("popl %esi\n\t" "popl %edi\n\t" @@ -315,10 +314,9 @@ __asm__("testl %eax,%eax\n\t" "jz exc_through"); - { /* clear the stack */ - register unsigned char *esp asm("esp"); - esp = ostack; - } + /* clear the stack */ + __asm__("leal -" STR(SAVED_REG_AREA) "(%ebp),%esp"); + { /* place the exception object on TOS */ register ExecEnv *cur_ee asm("edi"); register JHandle *excobj asm("edx"); @@ -357,7 +355,7 @@ "cmpl $3,%ecx\n\t" /* if (handler_state == 3) */ "jne exc_handler_shift_3\n\t" "popl %ecx\n\t" - "jmp exc_hanlder_shift_done\n\t" + "jmp exc_handler_shift_done\n\t" "exc_handler_shift_3:\n\t" "cmpl $2,%ecx\n\t" /* if (handler_stat == 2) */ "jne exc_handler_shift_4\n\t" @@ -371,8 +369,8 @@ "xorl %ecx,%ecx\n\t" "exc_handler_shift_done:"); - tgt = nativecode; - tgt += (int)cf->compiled_CatchFrame; + COMPILEDCODE(%edi); /* tgt(edi) = mb->CompiledCode */ + tgt/*edi*/ += (int)cf/*eax*/->compiled_CatchFrame; __asm__("jmp *%edi"); } __asm__("exc_through:"); @@ -773,7 +771,7 @@ BIPUSH_DEBUG1(%ecx);\ } - CODE_ILOAD_N(0, 0); + CODE_ILOAD_N(0, ); CODE_ILOAD_N(1, -4); CODE_ILOAD_N(2, -8); CODE_ILOAD_N(3, -12); @@ -811,7 +809,7 @@ LLOAD_N_ST02(OFF1, OFF2);\ } - CODE_LLOAD_N(0, -4, 0); + CODE_LLOAD_N(0, -4, ); CODE_LLOAD_N(1, -8, -4); CODE_LLOAD_N(2, -12, -8); CODE_LLOAD_N(3, -16, -12); @@ -1046,7 +1044,7 @@ BIPUSH_DEBUG1(%edx);\ } - CODE_ISTORE_N(0, 0); + CODE_ISTORE_N(0, ); CODE_ISTORE_N(1, -4); CODE_ISTORE_N(2, -8); CODE_ISTORE_N(3, -12); @@ -1082,7 +1080,7 @@ LSTORE_N_ST4(OFF1, OFF2);\ } - CODE_LSTORE_N(0, -4, 0); + CODE_LSTORE_N(0, -4, ); CODE_LSTORE_N(1, -8, -4); CODE_LSTORE_N(2, -12, -8); CODE_LSTORE_N(3, -16, -12); @@ -2131,7 +2129,7 @@ * %cl is shift count.\ * OP2 and OP3 are %eax and %edx.\ */\ - __asm__("rorb $1,%cl\n\t"\ + __asm__("rorb %cl\n\t"\ #ROP64 "l %cl," #OP2_REG "," #OP3_REG "\n\t"\ #ROP32 "l %cl," #OP2_REG "\n\t"\ #ROP64 "l %cl," #OP2_REG "," #OP3_REG "\n\t"\ @@ -2839,7 +2837,8 @@ CODE(opc_ret, ret, STANY, STSTA) { __asm__("movl " STR(CONST) "(%esi),%eax"); /* eax = vars[index] */ ILOAD_DEBUG1(%eax); - __asm__("addl %0,%%eax" : : "m" (nativecode)); /* eax += nativecode */ + COMPILEDCODE(%edi); /* edi = mb->CompiledCode */ + __asm__("addl %edi,%eax"); /* jump: "jmp *%eax" */ } @@ -2881,17 +2880,24 @@ "movl $" STR(CONST) ",%eax"); /* high */\ TBLSW_DEBUG1(INDEX);\ __asm__("subl %edi," #INDEX "\n\t" /* index -= low */\ - "subl %edi,%eax\n\t" /* high -= low */\ - "movl $" STR(CONST) ",%edi"); /* offset of the table */\ - __asm__("addl %0,%%edi" : : "m" (nativecode));\ - /* edi = addr. of the table */\ + "subl %edi,%eax"); /* high -= low */\ + \ + COMPILEDCODE(%edi); /* edi = mb->CompiledCode */\ + __asm__("pushl %edi"); /* push mb->CompiledCode */\ + \ + __asm__("addl $" STR(CONST) ",%edi"); /* edi += offset of the table */\ + /* edi = addr. of the table */\ __asm__("cmpl " #INDEX ",%eax\n\t" /* test high - index */\ "jb tblsw_st" #STATE "_default\n\t"\ "leal 8(%edi," #INDEX ",8),%edi\n\t" /* edi = tgt offset */\ "tblsw_st" #STATE "_default:\n\t"\ "movl (%edi),%eax");\ TBLSW_DEBUG2(%eax);\ - __asm__("addl %0,%%eax" : : "m" (nativecode)); /* eax = tgt addr. */\ + \ + __asm__("addl (%esp),%eax\n\t" /* eax += mb->CompiledCode */\ + "addl $4,%esp");\ + /* eax = target address */\ + \ __asm__("jmp *4(%edi)") CODE(opc_tableswitch, tableswitch, ST0, ST0) { @@ -2924,10 +2930,10 @@ # define LUSW_DEBUG1(KEY) \ if (runtime_debug) {\ DEBUG_IN;\ - __asm__("pushl %edi\n\tpushl %edi\n\tpushl %eax\n\tpushl " #KEY);\ - PUSH_CONSTSTR(" key: %d, npairs: %d, table offset: 0x%08x(%d)\n");\ + __asm__("pushl %eax\n\tpushl " #KEY);\ + PUSH_CONSTSTR(" key: %d, npairs: %d\n");\ __asm__("call " SYMBOL(printf) "@PLT\n\t"\ - "addl $20,%esp");\ + "addl $12,%esp");\ DEBUG_OUT;\ } # define LUSW_DEBUG2 \ @@ -2948,11 +2954,13 @@ #endif #define LUSW(KEY, STATE) \ + COMPILEDCODE(%edi);\ + __asm__("pushl %edi"); /* push mb->CompiledCode */\ + \ __asm__("movl $" STR(CONST) ",%eax"); /* npairs */\ - __asm__("movl $" STR(CONST) ",%edi"); /* offset of the table */\ + __asm__("addl $" STR(CONST) ",%edi"); /* offset of the table */\ + /* edi = addr. of the table */\ LUSW_DEBUG1(KEY);\ - __asm__("addl %0,%%edi" : : "m" (nativecode));\ - /* edi = addr. of the table */\ __asm__(\ "lusw_st" #STATE "_loop:\n\t"\ "cmpl (%edi)," #KEY "\n\t"\ @@ -2963,7 +2971,11 @@ "lusw_st" #STATE "_loopend:");\ LUSW_DEBUG2;\ __asm__("movl 4(%edi),%eax");\ - __asm__("addl %0,%%eax" : : "m" (nativecode)); /*eax = tgt addr. */\ + \ + __asm__("addl (%esp),%eax\n\t" /* eax += mb->CompiledCode */\ + "addl $4,%esp");\ + /* eax = tgt addr. */\ + \ __asm__("jmp *8(%edi)") @@ -3879,8 +3891,8 @@ LABEL "_test:") # define REWRITE_NEW(REWRITE_OFFSET) \ /* rewrite self */\ - __asm__("movl $" STR(CONST) ",%eax");\ - __asm__("addl %0,%%eax" : : "m" (nativecode));\ + COMPILEDCODE(%eax);\ + __asm__("addl $" STR(CONST) ",%eax");\ __asm__("movb $0x90," STR(REWRITE_OFFSET) "(%eax)\n\t"\ "movb $0x90," STR(REWRITE_OFFSET + 1) "(%eax)") #else diff -aruN shujit-0.2.5/code.h shujit-0.2.6/code.h --- shujit-0.2.5/code.h Sat Jan 9 21:18:17 1999 +++ shujit-0.2.6/code.h Wed Jan 20 18:12:30 1999 @@ -312,12 +312,14 @@ -#define METHOD_NLOCALS(MB, DST) \ - __asm__("movzwl 64(" #MB ")," #DST) #define METHOD_CLAZZ(MB, DST) \ __asm__("movl (" #MB ")," #DST) #define METHOD_SIGNATURE(MB) "4(" #MB ")" #define METHOD_NAME(MB) "8(" #MB ")" +#define METHOD_NLOCALS(MB, DST) \ + __asm__("movzwl 64(" #MB ")," #DST) +#define METHOD_COMPILEDCODE(MB, DST) \ + __asm__("movl 68(" #MB ")," #DST) #ifdef JITDO diff -aruN shujit-0.2.5/compiler.c shujit-0.2.6/compiler.c --- shujit-0.2.5/compiler.c Fri Jan 8 20:02:12 1999 +++ shujit-0.2.6/compiler.c Mon Jan 18 09:48:06 1999 @@ -30,6 +30,7 @@ int opt_codesize = 0; int opt_dontcmplvmcls = 0; int opt_igndisable = 0; +int opt_cmplclinit = 0; void *sym_compileAndInvokeMethod; void *sym_invokeJITCompiledMethod; @@ -55,7 +56,7 @@ static HObject *compilerCommand(HObject *); #define INITIALIZE_METHOD(MB) \ - {\ + if (opt_cmplclinit || strcmp((MB)->fb.name, "")) {\ (MB)->fb.access |= ACC_MACHINE_COMPILED;\ (MB)->invoker = sym_compileAndInvokeMethod;\ } @@ -108,6 +109,10 @@ else if (!strncmp(opt, "igndisable", 11)) { opt_igndisable = 1; if (!opt_quiet) printf(" option: igndisable\n"); + } + else if (!strncmp(opt, "cmplclinit", 11)) { + opt_cmplclinit = 1; + if (!opt_quiet) printf(" option: cmplclinit\n"); } opt = strtok(NULL, ", "); } diff -aruN shujit-0.2.5/compiler.h shujit-0.2.6/compiler.h --- shujit-0.2.5/compiler.h Thu Jan 7 14:26:09 1999 +++ shujit-0.2.6/compiler.h Thu Jan 21 17:16:40 1999 @@ -17,30 +17,30 @@ #include "x86tsc.h" #include "opcodes.h" -#define opc_invokeignored_nocheck 230 +#define opc_invokeignored_nocheck 230 /* 0xe6 */ -#define opc_getstatic2 231 +#define opc_getstatic2 231 /* 0xe7 */ #define opc_putstatic2 232 #define opc_getfield2 233 #define opc_putfield2 234 -#define opc_methodhead 235 +#define opc_methodhead 235 /* 0xeb */ #define opc_exception_handler 236 #define opc_methodtail 237 -#define opc_fill_cache 238 +#define opc_fill_cache 238 /* 0xee */ #define opc_array_check 239 -#define opc_iastore1 240 +#define opc_iastore1 240 /* 0xf0 */ #define opc_lastore1 241 -#define opc_stateto0 242 +#define opc_stateto0 242 /* 0xf2 */ #define opc_stateto1 243 #define opc_stateto2 244 #define opc_stateto3 245 #define opc_stateto4 246 -#define opc_goto_st0 247 +#define opc_goto_st0 247 /* 0xf7 */ #define opc_goto_st1 248 #define opc_goto_st2 249 #define opc_goto_st3 250 @@ -212,6 +212,8 @@ which is already loaded when JIT is initialized */ extern int opt_igndisable; /* make java.lang.Compiler#disable() void */ +extern int opt_cmplclinit; + /* compile class initializer */ extern void *sym_compileAndInvokeMethod; extern void *sym_invokeJITCompiledMethod; diff -aruN shujit-0.2.5/invoker.c shujit-0.2.6/invoker.c --- shujit-0.2.5/invoker.c Sun Jan 10 17:34:01 1999 +++ shujit-0.2.6/invoker.c Thu Jan 21 18:56:05 1999 @@ -12,6 +12,7 @@ #include /* for strcmp() */ #include "monitor.h" /* for monitor{Enter,Exit}() */ +#include "threads.h" /* for JavaStackSize */ #include "compiler.h" @@ -158,6 +159,7 @@ bool_t invokeJITCompiledMethod( JHandle *o, struct methodblock *mb, int args_size, ExecEnv *ee) { JavaFrame *old_frame, *frame; + struct methodblock *prev_method; /* for restack */ int access; stack_item *native_vars; #ifdef RUNTIME_DEBUG @@ -215,6 +217,39 @@ access = mb->fb.access; /* creates a new frame */ +#if 1 + { + JavaStack *stack = old_frame->javastack; + + frame = (JavaFrame *)(old_frame->optop + mb->nlocals); + if (frame->ostack + mb->maxstack >= stack->end_data) { + if (stack->next) stack = stack->next; + else { + if (stack->stack_so_far + JAVASTACK_CHUNK_SIZE * sizeof(stack_item) + > JavaStackSize) { + SignalError(ee, JAVAPKG "StackOverflowError", 0); + return FALSE; + } + if (!(stack = CreateNewJavaStack(ee, stack))) { + SignalError(ee, JAVAPKG "OutOfMemoryError", 0); + return FALSE; + } + } + frame = (JavaFrame *)(stack->data + mb->nlocals); + /* needless to copy args to a frame on new stack chunk */ + } + /* frame->constant_pool = cbConstantPool(fieldclass(&mb->fb)); */ + frame->returnpc = frame->lastpc = mb->code; + /* lastpc is not initialized in invoke*JavaMethod() */ + frame->optop = frame->ostack; + frame->vars = old_frame->optop; + frame->prev = old_frame; + frame->javastack = stack; + frame->current_method = mb; + + ee->current_frame = frame; + } /* create a new frame */ +#else if (access & ACC_SYNCHRONIZED) invokeSynchronizedJavaMethod(o, mb, args_size, ee); else @@ -223,18 +258,17 @@ frame = ee->current_frame; frame->lastpc = mb->code; /* lastpc is not initialized in invoke*JavaMethod() */ +#endif /* call */ /* restack from JVM stack to native stack */ - { - struct methodblock *prev_method = old_frame->current_method; - if (prev_method) { - if (prev_method->CompiledCode) { - /* called by compiled method */ - frame->vars = (stack_item *)old_frame->returnpc; - goto restack_done; - } + prev_method = old_frame->current_method; + if (prev_method) { + if (prev_method->CompiledCode) { + /* called by compiled method */ + frame->vars = (stack_item *)old_frame->returnpc; + goto restack_done; } } @@ -305,6 +339,18 @@ } #endif + + if (!(access & ACC_SYNCHRONIZED)) + frame->monitor = 0; + else { + frame->monitor = o; + monitorEnter(obj_monitor(o)); + } + +#ifdef ENABLE_PROFILING + if (java_monitor) frame->mon_starttime = now(); +#endif + #if 0 printf("%x\n", mb->CompiledCode); #endif @@ -316,8 +362,14 @@ mb->CompiledCode)(o, mb, args_size, ee); #endif - if (frame->monitor) + if (access & ACC_SYNCHRONIZED) /* if (frame->monitor) */ monitorExit(obj_monitor(frame->monitor)); + +#ifdef ENABLE_PROFILING + if (java_monitor) + java_mon(prev_method, mb, now() - frame->mon_starttime); +#endif + ee->current_frame = frame->prev; #ifdef RUNTIME_DEBUG diff -aruN shujit-0.2.5/txt/benchmark-SS3000 shujit-0.2.6/txt/benchmark-SS3000 --- shujit-0.2.5/txt/benchmark-SS3000 Wed Jan 6 23:55:55 1999 +++ shujit-0.2.6/txt/benchmark-SS3000 Thu Jan 21 19:04:35 1999 @@ -12,6 +12,13 @@ Iview Valetta.jpg 456 482 647 msec (*) 非常にばらつく TYA12: 4833-10668, 990104: 773-7469 + plain TYA12v3 990120 +Sieve 96 317 398 times +TestOpcodeField 4037 1310 1309 msec +TestOpcodeStatic 3095 429 258 msec +TestFinalStatic 12299 7362(*) 1116(*) msec +Iview Valetta.jpg 447 460 631 msec + [Linpack Benchmark -- Java Version] plain TYA12 990104 @@ -26,6 +33,11 @@ 192 859 362 465 256 855 384 481 + plain TYA12v3 990120 +128 809 348 398 +192 827 351 382 +256 853 348 400 + [CaffeineMark 3.0] interpreter @@ -42,28 +54,29 @@ CM3 391 TYA - 1.2 1.2(*) -Sieve 822 780 -Loop 1558 1404 -Logic 2887 2872 -String 1410 1372 -Float 993 915 -Method 888 877 -Graphics605 571 -Image 320 312 -Dialog 71 65 -CM3 735 699 + 1.2 1.2(*) 1.2v3 +Sieve 822 780 822 +Loop 1558 1404 1543 +Logic 2887 2872 2895 +String 1410 1372 1496 +Float 993 915 992 +Method 888 877 933 +Graphics605 571 595 +Image 320 312 308 +Dialog 71 65 69 +CM3 735 699 737 (*) EXCEPTIONS_BY_SIGNALS を #undef shuJIT - 990104 990106 -Sieve 890 891 -Loop 1712 1710 -Logic 2882 2891 -String 1015 1007 -Float 1038 1030 -Method 146 144 -Graphics472 481 -Image 303 304 -Dialog 63 63 -CM3 567 567 + 990104 990106 990120 990120 990121 +Sieve 890 891 892 879 891 +Loop 1712 1710 1703 1712 1712 +Logic 2882 2891 2881 2885 2877 +String 1015 1007 1017 1004 1116 +Float 1038 1030 1043 1046 1030 +Method 146 144 189 187 199 +Graphics472 481 495 513 494 +Image 303 304 298 294 303 +Dialog 63 63 63 65 68 +CM3 567 567 582 587 600 + (cmplclinit) diff -aruN shujit-0.2.5/txt/memo shujit-0.2.6/txt/memo --- shujit-0.2.5/txt/memo Sun Jan 10 18:36:25 1999 +++ shujit-0.2.6/txt/memo Wed Jan 20 23:07:42 1999 @@ -4,7 +4,6 @@ - cur_frame->lastpc = ... - stackpointer += (args_size - 1); - signal を利用して null check を省く。 - - static initializer をコンパイルしない。 - スタック上の要素の性質 (例: 配列のサイズ) を trace し、 省ける各種チェック (例: 添字の範囲) を省く。仮想スタックライブラリを用意。 - stack 上の倍精度浮動小数点数を 8バイト境界に align する。 @@ -17,20 +16,22 @@ JavaFrame のメンバ ostack と optop が同じ領域にあることを 仮定したコードがある。 JavaFrame の存在を仮定したコードが多い。 - - JavaFrame の作成を省く。 - Object# の呼び出しを削除する。 invokeignored_quick への recode 条件を調べる。 + - 浮動小数点数を FPU のレジスタに載せたままにしておく。 + JVM のレジスタに載せない。 - bytecode の静的最適化。 invokeignored_quick への変換。 [ifa]store{,_N}, [ifa]load{,_N} で、メモリからの読みだしを省く。 + - lcmp, ifXX といった定番コード列について最適化。 - invoke(Synchronized)JavaMethod() の代替を用意、処理を軽減する。 - CompilerContext をむやみに free(), malloc() しない。 排他制御が必要。-> thread library を使ってしまう。 - native 命令列の書き換え。 invoke -> invokevirtual*object* 相当など。 obj_array_methodtable() ではなく obj_methodtable() が使える。 + - JavaFrame の作成を省く。 - vars[0..] をレジスタにのせてキャッシュする。 - - lcmp, ifXX といった定番コード列について最適化。 - 例外ハンドラを offset ではなく絶対アドレスで扱う。 - lookupswitch 命令の検索アルゴリズムを改良する。 - Address Generation Interlock(AGI) (MMX 本 pp.95,99) を避ける。 @@ -59,6 +60,7 @@ javac の、フックをかけられる箇所を探す。 Done + - class initializer をコンパイルしない。 - java.lang.Compiler#enable(),disable() が働くようにする。 Swing 1.1 の SwingSet でテスト。appleviewer SwingSetApplet.html - __{mul,div,mod}di3 を呼び出さないようにする。 @@ -123,8 +125,6 @@ TYA 1.0 の bugs - 上記 known bugs。:) - 5 次元以上の配列を作成するコードをコンパイルできない。 - - NaN を integer に変換すると 0 にならない。 - - null を throw しようとすると、制御がおかしくなる。 JDK 1.1.6, Version 2 (by Steve Byrne) - native method, sun.awt.motif.MChoicePeer#pReshape (IIII)V