video_writer::copy_image::copy_image(uint32_t width, uint32_t height, uint32_t pitch) { uint32_t w_byte = width * 4 / 16; uint32_t index = 0; std::function<void()> funcs[3] = { [this] { mov16(); }, [this] { mov32(); }, [this] { mov64(); } }; for (; index < 2; ++index){ if ((w_byte & 1) == 1) { break; } else { w_byte = w_byte / 2; } } mov(r8, w_byte); mov(r9, height); mov(r10, pitch * 2); L("L2"); mov(rax, r8); L("L1"); funcs[index](); sub(rax, 1); jnz("L1"); sub(rcx, r10); sub(r9, 1); jnz("L2"); vzeroupper(); ret(); }
address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { const char *name; switch (type) { case T_BOOLEAN: name = "jni_fast_GetBooleanField"; break; case T_BYTE: name = "jni_fast_GetByteField"; break; case T_CHAR: name = "jni_fast_GetCharField"; break; case T_SHORT: name = "jni_fast_GetShortField"; break; case T_INT: name = "jni_fast_GetIntField"; break; default: ShouldNotReachHere(); } ResourceMark rm; BufferBlob* b = BufferBlob::create(name, BUFFER_SIZE*wordSize); address fast_entry = b->instructions_begin(); CodeBuffer cbuf(fast_entry, b->instructions_size()); MacroAssembler* masm = new MacroAssembler(&cbuf); Label slow; // stack layout: offset from rsp (in words): // return pc 0 // jni env 1 // obj 2 // jfieldID 3 ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr()); __ mov32 (rcx, counter); __ testb (rcx, 1); __ jcc (Assembler::notZero, slow); if (os::is_MP()) { __ mov(rax, rcx); __ andptr(rax, 1); // rax, must end up 0 __ movptr(rdx, Address(rsp, rax, Address::times_1, 2*wordSize)); // obj, notice rax, is 0. // rdx is data dependent on rcx. } else { __ movptr (rdx, Address(rsp, 2*wordSize)); // obj } __ movptr(rax, Address(rsp, 3*wordSize)); // jfieldID __ movptr(rdx, Address(rdx, 0)); // *obj __ shrptr (rax, 2); // offset assert(count < LIST_CAPACITY, "LIST_CAPACITY too small"); speculative_load_pclist[count] = __ pc(); switch (type) { case T_BOOLEAN: __ movzbl (rax, Address(rdx, rax, Address::times_1)); break; case T_BYTE: __ movsbl (rax, Address(rdx, rax, Address::times_1)); break; case T_CHAR: __ movzwl (rax, Address(rdx, rax, Address::times_1)); break; case T_SHORT: __ movswl (rax, Address(rdx, rax, Address::times_1)); break; case T_INT: __ movl (rax, Address(rdx, rax, Address::times_1)); break; default: ShouldNotReachHere(); } Address ca1; if (os::is_MP()) { __ lea(rdx, counter); __ xorptr(rdx, rax); __ xorptr(rdx, rax); __ cmp32(rcx, Address(rdx, 0)); // ca1 is the same as ca because // rax, ^ counter_addr ^ rax, = address // ca1 is data dependent on rax,. } else { __ cmp32(rcx, counter); } __ jcc (Assembler::notEqual, slow); #ifndef _WINDOWS __ ret (0); #else // __stdcall calling convention __ ret (3*wordSize); #endif slowcase_entry_pclist[count++] = __ pc(); __ bind (slow); address slow_case_addr; switch (type) { case T_BOOLEAN: slow_case_addr = jni_GetBooleanField_addr(); break; case T_BYTE: slow_case_addr = jni_GetByteField_addr(); break; case T_CHAR: slow_case_addr = jni_GetCharField_addr(); break; case T_SHORT: slow_case_addr = jni_GetShortField_addr(); break; case T_INT: slow_case_addr = jni_GetIntField_addr(); } // tail call __ jump (ExternalAddress(slow_case_addr)); __ flush (); #ifndef _WINDOWS return fast_entry; #else switch (type) { case T_BOOLEAN: jni_fast_GetBooleanField_fp = (GetBooleanField_t)fast_entry; break; case T_BYTE: jni_fast_GetByteField_fp = (GetByteField_t)fast_entry; break; case T_CHAR: jni_fast_GetCharField_fp = (GetCharField_t)fast_entry; break; case T_SHORT: jni_fast_GetShortField_fp = (GetShortField_t)fast_entry; break; case T_INT: jni_fast_GetIntField_fp = (GetIntField_t)fast_entry; } return os::win32::fast_jni_accessor_wrapper(type); #endif }
address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) { const char *name; switch (type) { case T_FLOAT: name = "jni_fast_GetFloatField"; break; case T_DOUBLE: name = "jni_fast_GetDoubleField"; break; default: ShouldNotReachHere(); } ResourceMark rm; BufferBlob* b = BufferBlob::create(name, BUFFER_SIZE*wordSize); address fast_entry = b->instructions_begin(); CodeBuffer cbuf(fast_entry, b->instructions_size()); MacroAssembler* masm = new MacroAssembler(&cbuf); Label slow_with_pop, slow; // stack layout: offset from rsp (in words): // return pc 0 // jni env 1 // obj 2 // jfieldID 3 ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr()); __ mov32 (rcx, counter); __ testb (rcx, 1); __ jcc (Assembler::notZero, slow); if (os::is_MP()) { __ mov(rax, rcx); __ andptr(rax, 1); // rax, must end up 0 __ movptr(rdx, Address(rsp, rax, Address::times_1, 2*wordSize)); // obj, notice rax, is 0. // rdx is data dependent on rcx. } else { __ movptr(rdx, Address(rsp, 2*wordSize)); // obj } __ movptr(rax, Address(rsp, 3*wordSize)); // jfieldID __ movptr(rdx, Address(rdx, 0)); // *obj __ shrptr(rax, 2); // offset assert(count < LIST_CAPACITY, "LIST_CAPACITY too small"); speculative_load_pclist[count] = __ pc(); switch (type) { #ifndef _LP64 case T_FLOAT: __ fld_s (Address(rdx, rax, Address::times_1)); break; case T_DOUBLE: __ fld_d (Address(rdx, rax, Address::times_1)); break; #else case T_FLOAT: __ movflt (xmm0, Address(robj, roffset, Address::times_1)); break; case T_DOUBLE: __ movdbl (xmm0, Address(robj, roffset, Address::times_1)); break; #endif // _LP64 default: ShouldNotReachHere(); } Address ca1; if (os::is_MP()) { __ fst_s (Address(rsp, -4)); __ lea(rdx, counter); __ movl (rax, Address(rsp, -4)); // garbage hi-order bits on 64bit are harmless. __ xorptr(rdx, rax); __ xorptr(rdx, rax); __ cmp32(rcx, Address(rdx, 0)); // rax, ^ counter_addr ^ rax, = address // ca1 is data dependent on the field // access. } else { __ cmp32(rcx, counter); } __ jcc (Assembler::notEqual, slow_with_pop); #ifndef _WINDOWS __ ret (0); #else // __stdcall calling convention __ ret (3*wordSize); #endif __ bind (slow_with_pop); // invalid load. pop FPU stack. __ fstp_d (0); slowcase_entry_pclist[count++] = __ pc(); __ bind (slow); address slow_case_addr; switch (type) { case T_FLOAT: slow_case_addr = jni_GetFloatField_addr(); break; case T_DOUBLE: slow_case_addr = jni_GetDoubleField_addr(); break; default: ShouldNotReachHere(); } // tail call __ jump (ExternalAddress(slow_case_addr)); __ flush (); #ifndef _WINDOWS return fast_entry; #else switch (type) { case T_FLOAT: jni_fast_GetFloatField_fp = (GetFloatField_t)fast_entry; break; case T_DOUBLE: jni_fast_GetDoubleField_fp = (GetDoubleField_t)fast_entry; } return os::win32::fast_jni_accessor_wrapper(type); #endif }
address JNI_FastGetField::generate_fast_get_long_field() { const char *name = "jni_fast_GetLongField"; ResourceMark rm; BufferBlob* b = BufferBlob::create(name, BUFFER_SIZE*wordSize); address fast_entry = b->instructions_begin(); CodeBuffer cbuf(fast_entry, b->instructions_size()); MacroAssembler* masm = new MacroAssembler(&cbuf); Label slow; // stack layout: offset from rsp (in words): // old rsi 0 // return pc 1 // jni env 2 // obj 3 // jfieldID 4 ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr()); __ push (rsi); __ mov32 (rcx, counter); __ testb (rcx, 1); __ jcc (Assembler::notZero, slow); if (os::is_MP()) { __ mov(rax, rcx); __ andptr(rax, 1); // rax, must end up 0 __ movptr(rdx, Address(rsp, rax, Address::times_1, 3*wordSize)); // obj, notice rax, is 0. // rdx is data dependent on rcx. } else { __ movptr(rdx, Address(rsp, 3*wordSize)); // obj } __ movptr(rsi, Address(rsp, 4*wordSize)); // jfieldID __ movptr(rdx, Address(rdx, 0)); // *obj __ shrptr(rsi, 2); // offset assert(count < LIST_CAPACITY-1, "LIST_CAPACITY too small"); speculative_load_pclist[count++] = __ pc(); __ movptr(rax, Address(rdx, rsi, Address::times_1)); #ifndef _LP64 speculative_load_pclist[count] = __ pc(); __ movl(rdx, Address(rdx, rsi, Address::times_1, 4)); #endif // _LP64 if (os::is_MP()) { __ lea(rsi, counter); __ xorptr(rsi, rdx); __ xorptr(rsi, rax); __ xorptr(rsi, rdx); __ xorptr(rsi, rax); __ cmp32(rcx, Address(rsi, 0)); // ca1 is the same as ca because // rax, ^ rdx ^ counter_addr ^ rax, ^ rdx = address // ca1 is data dependent on both rax, and rdx. } else { __ cmp32(rcx, counter); } __ jcc (Assembler::notEqual, slow); __ pop (rsi); #ifndef _WINDOWS __ ret (0); #else // __stdcall calling convention __ ret (3*wordSize); #endif slowcase_entry_pclist[count-1] = __ pc(); slowcase_entry_pclist[count++] = __ pc(); __ bind (slow); __ pop (rsi); address slow_case_addr = jni_GetLongField_addr();; // tail call __ jump (ExternalAddress(slow_case_addr)); __ flush (); #ifndef _WINDOWS return fast_entry; #else jni_fast_GetLongField_fp = (GetLongField_t)fast_entry; return os::win32::fast_jni_accessor_wrapper(T_LONG); #endif }
address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { const char *name; switch (type) { case T_BOOLEAN: name = "jni_fast_GetBooleanField"; break; case T_BYTE: name = "jni_fast_GetByteField"; break; case T_CHAR: name = "jni_fast_GetCharField"; break; case T_SHORT: name = "jni_fast_GetShortField"; break; case T_INT: name = "jni_fast_GetIntField"; break; case T_LONG: name = "jni_fast_GetLongField"; break; default: ShouldNotReachHere(); } ResourceMark rm; BufferBlob* b = BufferBlob::create(name, BUFFER_SIZE); address fast_entry = b->instructions_begin(); CodeBuffer cbuf(fast_entry, b->instructions_size()); MacroAssembler* masm = new MacroAssembler(&cbuf); Label slow; ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr()); __ mov32 (rcounter, counter); __ mov (robj, c_rarg1); __ testb (rcounter, 1); __ jcc (Assembler::notZero, slow); if (os::is_MP()) { __ xorptr(robj, rcounter); __ xorptr(robj, rcounter); // obj, since // robj ^ rcounter ^ rcounter == robj // robj is data dependent on rcounter. } __ movptr(robj, Address(robj, 0)); // *obj __ mov (roffset, c_rarg2); __ shrptr(roffset, 2); // offset assert(count < LIST_CAPACITY, "LIST_CAPACITY too small"); speculative_load_pclist[count] = __ pc(); switch (type) { case T_BOOLEAN: __ movzbl (rax, Address(robj, roffset, Address::times_1)); break; case T_BYTE: __ movsbl (rax, Address(robj, roffset, Address::times_1)); break; case T_CHAR: __ movzwl (rax, Address(robj, roffset, Address::times_1)); break; case T_SHORT: __ movswl (rax, Address(robj, roffset, Address::times_1)); break; case T_INT: __ movl (rax, Address(robj, roffset, Address::times_1)); break; case T_LONG: __ movq (rax, Address(robj, roffset, Address::times_1)); break; default: ShouldNotReachHere(); } if (os::is_MP()) { __ lea(rcounter_addr, counter); // ca is data dependent on rax. __ xorptr(rcounter_addr, rax); __ xorptr(rcounter_addr, rax); __ cmpl (rcounter, Address(rcounter_addr, 0)); } else { __ cmp32 (rcounter, counter); } __ jcc (Assembler::notEqual, slow); __ ret (0); slowcase_entry_pclist[count++] = __ pc(); __ bind (slow); address slow_case_addr; switch (type) { case T_BOOLEAN: slow_case_addr = jni_GetBooleanField_addr(); break; case T_BYTE: slow_case_addr = jni_GetByteField_addr(); break; case T_CHAR: slow_case_addr = jni_GetCharField_addr(); break; case T_SHORT: slow_case_addr = jni_GetShortField_addr(); break; case T_INT: slow_case_addr = jni_GetIntField_addr(); break; case T_LONG: slow_case_addr = jni_GetLongField_addr(); } // tail call __ jump (ExternalAddress(slow_case_addr)); __ flush (); return fast_entry; }
address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) { const char *name = NULL; switch (type) { case T_FLOAT: name = "jni_fast_GetFloatField"; break; case T_DOUBLE: name = "jni_fast_GetDoubleField"; break; default: ShouldNotReachHere(); } ResourceMark rm; BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE); CodeBuffer cbuf(blob); MacroAssembler* masm = new MacroAssembler(&cbuf); address fast_entry = __ pc(); Label slow; ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr()); __ mov32 (rcounter, counter); __ mov (robj, c_rarg1); __ testb (rcounter, 1); __ jcc (Assembler::notZero, slow); if (os::is_MP()) { __ xorptr(robj, rcounter); __ xorptr(robj, rcounter); // obj, since // robj ^ rcounter ^ rcounter == robj // robj is data dependent on rcounter. } __ clear_jweak_tag(robj); __ movptr(robj, Address(robj, 0)); // *obj __ mov (roffset, c_rarg2); __ shrptr(roffset, 2); // offset assert(count < LIST_CAPACITY, "LIST_CAPACITY too small"); speculative_load_pclist[count] = __ pc(); switch (type) { case T_FLOAT: __ movflt (xmm0, Address(robj, roffset, Address::times_1)); break; case T_DOUBLE: __ movdbl (xmm0, Address(robj, roffset, Address::times_1)); break; default: ShouldNotReachHere(); } if (os::is_MP()) { __ lea(rcounter_addr, counter); __ movdq (rax, xmm0); // counter address is data dependent on xmm0. __ xorptr(rcounter_addr, rax); __ xorptr(rcounter_addr, rax); __ cmpl (rcounter, Address(rcounter_addr, 0)); } else { __ cmp32 (rcounter, counter); } __ jcc (Assembler::notEqual, slow); __ ret (0); slowcase_entry_pclist[count++] = __ pc(); __ bind (slow); address slow_case_addr = NULL; switch (type) { case T_FLOAT: slow_case_addr = jni_GetFloatField_addr(); break; case T_DOUBLE: slow_case_addr = jni_GetDoubleField_addr(); } // tail call __ jump (ExternalAddress(slow_case_addr)); __ flush (); return fast_entry; }