< prev index next >

src/cpu/x86/vm/templateTable_x86.cpp

Print this page




2857     __ get_cache_and_index_at_bcp(cache, index, 1);
2858     __ bind(L1);
2859   }
2860 }
2861 
2862 void TemplateTable::pop_and_check_object(Register r) {
2863   __ pop_ptr(r);
2864   __ null_check(r);  // for field access must check obj.
2865   __ verify_oop(r);
2866 }
2867 
2868 void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteControl rc) {
2869   transition(vtos, vtos);
2870 
2871   const Register cache = rcx;
2872   const Register index = rdx;
2873   const Register obj   = LP64_ONLY(c_rarg3) NOT_LP64(rcx);
2874   const Register off   = rbx;
2875   const Register flags = rax;
2876   const Register bc    = LP64_ONLY(c_rarg3) NOT_LP64(rcx); // uses same reg as obj, so don't mix them

2877 
2878   resolve_cache_and_index(byte_no, cache, index, sizeof(u2));
2879   jvmti_post_field_access(cache, index, is_static, false);
2880   load_field_cp_cache_entry(obj, cache, index, off, flags, is_static);
2881 
2882   const Address field(obj, off, Address::times_1, 0*wordSize);
2883   NOT_LP64(const Address hi(obj, off, Address::times_1, 1*wordSize));
2884 
2885   Label Done, notByte, notBool, notInt, notShort, notChar, notLong, notFloat, notObj, notValueType, notDouble;
2886 


2887   __ shrl(flags, ConstantPoolCacheEntry::tos_state_shift);
2888   // Make sure we don't need to mask edx after the above shift
2889   assert(btos == 0, "change code, btos != 0");
2890 
2891   __ andl(flags, ConstantPoolCacheEntry::tos_state_mask);
2892 
2893   __ jcc(Assembler::notZero, notByte);
2894   // btos
2895   if (!is_static) pop_and_check_object(obj);
2896   __ load_signed_byte(rax, field);
2897   __ push(btos);
2898   // Rewrite bytecode to be faster
2899   if (!is_static && rc == may_rewrite) {
2900     patch_bytecode(Bytecodes::_fast_bgetfield, bc, rbx);
2901   }
2902   __ jmp(Done);
2903 
2904   __ bind(notByte);
2905 
2906   __ cmpl(flags, qtos);
2907   __ jcc(Assembler::notEqual, notValueType);
2908   // qtos
2909   if (is_static) {
2910     Label initialized;
2911     // Issue below if the static field has not been initialized yet
2912     __ load_heap_oop(rax, field);
2913     __ testptr(rax, rax);
2914     __ jcc(Assembler::notZero, initialized);

2915     __ call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::initialize_static_value_field),
2916          obj, off);
2917     __ verify_oop(rax);
2918     __ bind(initialized);
2919     __ push(qtos);
2920   } else {
2921     pop_and_check_object(obj);

2922     call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::qgetfield),
2923         obj, off);
2924     __ verify_oop(rax);
2925     __ push(qtos);
2926     // Bytecode rewrite?
2927   }
2928   __ jmp(Done);
2929 
2930   __ bind(notValueType);
2931 
2932   if (!is_static) pop_and_check_object(obj);
2933 
2934   __ cmpl(flags, ztos);
2935   __ jcc(Assembler::notEqual, notBool);
2936 
2937   // ztos (same code as btos)
2938   __ load_signed_byte(rax, field);
2939   __ push(ztos);
2940   // Rewrite bytecode to be faster
2941   if (!is_static && rc == may_rewrite) {
2942     // use btos rewriting, no truncating to t/f bit is needed for getfield.
2943     patch_bytecode(Bytecodes::_fast_bgetfield, bc, rbx);


3158     // c_rarg2: cache entry pointer
3159     // c_rarg3: jvalue object on the stack
3160     __ call_VM(noreg,
3161                CAST_FROM_FN_PTR(address,
3162                                 InterpreterRuntime::post_field_modification),
3163                RBX, robj, RCX);
3164     __ get_cache_and_index_at_bcp(cache, index, 1);
3165     __ bind(L1);
3166   }
3167 }
3168 
3169 void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteControl rc) {
3170   transition(vtos, vtos);
3171 
3172   const Register cache = rcx;
3173   const Register index = rdx;
3174   const Register obj   = rcx;
3175   const Register off   = rbx;
3176   const Register flags = rax;
3177   const Register bc    = LP64_ONLY(c_rarg3) NOT_LP64(rcx);

3178 
3179   resolve_cache_and_index(byte_no, cache, index, sizeof(u2));
3180   jvmti_post_field_mod(cache, index, is_static);
3181   load_field_cp_cache_entry(obj, cache, index, off, flags, is_static);
3182 
3183   // [jk] not needed currently
3184   // volatile_barrier(Assembler::Membar_mask_bits(Assembler::LoadStore |
3185   //                                              Assembler::StoreStore));
3186 
3187   Label notVolatile, Done;
3188   __ movl(rdx, flags);
3189   __ shrl(rdx, ConstantPoolCacheEntry::is_volatile_shift);
3190   __ andl(rdx, 0x1);
3191 
3192   // field addresses
3193   const Address field(obj, off, Address::times_1, 0*wordSize);
3194   NOT_LP64( const Address hi(obj, off, Address::times_1, 1*wordSize);)
3195 
3196   Label notByte, notBool, notInt, notShort, notChar,
3197         notLong, notFloat, notObj, notValueType, notDouble;
3198 
3199   __ shrl(flags, ConstantPoolCacheEntry::tos_state_shift);
3200 
3201   assert(btos == 0, "change code, btos != 0");
3202   __ andl(flags, ConstantPoolCacheEntry::tos_state_mask);
3203   __ jcc(Assembler::notZero, notByte);
3204 
3205   // btos
3206   {
3207     __ pop(btos);
3208     if (!is_static) pop_and_check_object(obj);
3209     __ movb(field, rax);
3210     if (!is_static && rc == may_rewrite) {


3237   {
3238     __ pop(atos);
3239     if (!is_static) pop_and_check_object(obj);
3240     // Store into the field
3241     do_oop_store(_masm, field, rax, _bs->kind(), false);
3242     if (!is_static && rc == may_rewrite) {
3243       patch_bytecode(Bytecodes::_fast_aputfield, bc, rbx, true, byte_no);
3244     }
3245     __ jmp(Done);
3246   }
3247 
3248   __ bind(notObj);
3249   __ cmpl(flags, qtos);
3250   __ jcc(Assembler::notEqual, notValueType);
3251 
3252   // qtos
3253   {
3254     __ pop(qtos); // => rax == value
3255     if (!is_static) {
3256       // value types in non-static fields are embedded
3257       __ movl(rcx, off);
3258       pop_and_check_object(rbx);
3259       call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::qputfield),
3260           rbx, rax, rcx);
3261       __ jmp(notVolatile); // value types are never volatile
3262     } else {
3263       // Store into the static field
3264       // Value types in static fields are currently handled with indirection
3265       // but a copy to the Java heap might be required if the value is currently
3266       // stored in a thread local buffer
3267       call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::qputstatic), rax);
3268     }
3269     __ jmp(Done);
3270   }
3271 
3272   __ bind(notValueType);
3273   __ cmpl(flags, itos);
3274   __ jcc(Assembler::notEqual, notInt);
3275 
3276   // itos
3277   {
3278     __ pop(itos);
3279     if (!is_static) pop_and_check_object(obj);
3280     __ movl(field, rax);
3281     if (!is_static && rc == may_rewrite) {
3282       patch_bytecode(Bytecodes::_fast_iputfield, bc, rbx, true, byte_no);
3283     }
3284     __ jmp(Done);
3285   }
3286 
3287   __ bind(notInt);


3384 
3385   // dtos
3386   {
3387     __ pop(dtos);
3388     if (!is_static) pop_and_check_object(obj);
3389     __ store_double(field);
3390     if (!is_static && rc == may_rewrite) {
3391       patch_bytecode(Bytecodes::_fast_dputfield, bc, rbx, true, byte_no);
3392     }
3393   }
3394 
3395 #ifdef ASSERT
3396   __ jmp(Done);
3397 
3398   __ bind(notDouble);
3399   __ stop("Bad state");
3400 #endif
3401 
3402   __ bind(Done);
3403 



3404   // Check for volatile store
3405   __ testl(rdx, rdx);
3406   __ jcc(Assembler::zero, notVolatile);
3407   volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad |
3408                                                Assembler::StoreStore));
3409   __ bind(notVolatile);
3410 }
3411 
3412 void TemplateTable::putfield(int byte_no) {
3413   putfield_or_static(byte_no, false);
3414 }
3415 
3416 void TemplateTable::nofast_putfield(int byte_no) {
3417   putfield_or_static(byte_no, false, may_not_rewrite);
3418 }
3419 
3420 void TemplateTable::putstatic(int byte_no) {
3421   putfield_or_static(byte_no, true);
3422 }
3423 
3424 void TemplateTable::jvmti_post_fast_field_mod() {
3425 




2857     __ get_cache_and_index_at_bcp(cache, index, 1);
2858     __ bind(L1);
2859   }
2860 }
2861 
2862 void TemplateTable::pop_and_check_object(Register r) {
2863   __ pop_ptr(r);
2864   __ null_check(r);  // for field access must check obj.
2865   __ verify_oop(r);
2866 }
2867 
2868 void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteControl rc) {
2869   transition(vtos, vtos);
2870 
2871   const Register cache = rcx;
2872   const Register index = rdx;
2873   const Register obj   = LP64_ONLY(c_rarg3) NOT_LP64(rcx);
2874   const Register off   = rbx;
2875   const Register flags = rax;
2876   const Register bc    = LP64_ONLY(c_rarg3) NOT_LP64(rcx); // uses same reg as obj, so don't mix them
2877   const Register flags2 = rdx;
2878 
2879   resolve_cache_and_index(byte_no, cache, index, sizeof(u2));
2880   jvmti_post_field_access(cache, index, is_static, false);
2881   load_field_cp_cache_entry(obj, cache, index, off, flags, is_static);
2882 
2883   const Address field(obj, off, Address::times_1, 0*wordSize);
2884   NOT_LP64(const Address hi(obj, off, Address::times_1, 1*wordSize));
2885 
2886   Label Done, notByte, notBool, notInt, notShort, notChar, notLong, notFloat, notObj, notValueType, notDouble;
2887 
2888   __ movl(flags2, flags);
2889 
2890   __ shrl(flags, ConstantPoolCacheEntry::tos_state_shift);
2891   // Make sure we don't need to mask edx after the above shift
2892   assert(btos == 0, "change code, btos != 0");
2893 
2894   __ andl(flags, ConstantPoolCacheEntry::tos_state_mask);
2895 
2896   __ jcc(Assembler::notZero, notByte);
2897   // btos
2898   if (!is_static) pop_and_check_object(obj);
2899   __ load_signed_byte(rax, field);
2900   __ push(btos);
2901   // Rewrite bytecode to be faster
2902   if (!is_static && rc == may_rewrite) {
2903     patch_bytecode(Bytecodes::_fast_bgetfield, bc, rbx);
2904   }
2905   __ jmp(Done);
2906 
2907   __ bind(notByte);
2908 
2909   __ cmpl(flags, qtos);
2910   __ jcc(Assembler::notEqual, notValueType);
2911   // qtos
2912   if (is_static) {
2913     Label initialized;
2914     // Issue below if the static field has not been initialized yet
2915     __ load_heap_oop(rax, field);
2916     __ testptr(rax, rax);
2917     __ jcc(Assembler::notZero, initialized);
2918     __ andl(flags2, ConstantPoolCacheEntry::field_index_mask);
2919     __ call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::initialize_static_value_field),
2920          obj, flags2);
2921     __ verify_oop(rax);
2922     __ bind(initialized);
2923     __ push(qtos);
2924   } else {
2925     pop_and_check_object(obj);
2926     __ andl(flags2, ConstantPoolCacheEntry::field_index_mask);
2927     call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::qgetfield),
2928         obj, flags2);
2929     __ verify_oop(rax);
2930     __ push(qtos);
2931     // Bytecode rewrite?
2932   }
2933   __ jmp(Done);
2934 
2935   __ bind(notValueType);
2936 
2937   if (!is_static) pop_and_check_object(obj);
2938 
2939   __ cmpl(flags, ztos);
2940   __ jcc(Assembler::notEqual, notBool);
2941 
2942   // ztos (same code as btos)
2943   __ load_signed_byte(rax, field);
2944   __ push(ztos);
2945   // Rewrite bytecode to be faster
2946   if (!is_static && rc == may_rewrite) {
2947     // use btos rewriting, no truncating to t/f bit is needed for getfield.
2948     patch_bytecode(Bytecodes::_fast_bgetfield, bc, rbx);


3163     // c_rarg2: cache entry pointer
3164     // c_rarg3: jvalue object on the stack
3165     __ call_VM(noreg,
3166                CAST_FROM_FN_PTR(address,
3167                                 InterpreterRuntime::post_field_modification),
3168                RBX, robj, RCX);
3169     __ get_cache_and_index_at_bcp(cache, index, 1);
3170     __ bind(L1);
3171   }
3172 }
3173 
3174 void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteControl rc) {
3175   transition(vtos, vtos);
3176 
3177   const Register cache = rcx;
3178   const Register index = rdx;
3179   const Register obj   = rcx;
3180   const Register off   = rbx;
3181   const Register flags = rax;
3182   const Register bc    = LP64_ONLY(c_rarg3) NOT_LP64(rcx);
3183   const Register flags2 = rdx;
3184 
3185   resolve_cache_and_index(byte_no, cache, index, sizeof(u2));
3186   jvmti_post_field_mod(cache, index, is_static);
3187   load_field_cp_cache_entry(obj, cache, index, off, flags, is_static);
3188 
3189   // [jk] not needed currently
3190   // volatile_barrier(Assembler::Membar_mask_bits(Assembler::LoadStore |
3191   //                                              Assembler::StoreStore));
3192 
3193   Label notVolatile, Done;
3194 
3195   __ movl(flags2, flags);

3196 
3197   // field addresses
3198   const Address field(obj, off, Address::times_1, 0*wordSize);
3199   NOT_LP64( const Address hi(obj, off, Address::times_1, 1*wordSize);)
3200 
3201   Label notByte, notBool, notInt, notShort, notChar,
3202         notLong, notFloat, notObj, notValueType, notDouble;
3203 
3204   __ shrl(flags, ConstantPoolCacheEntry::tos_state_shift);
3205 
3206   assert(btos == 0, "change code, btos != 0");
3207   __ andl(flags, ConstantPoolCacheEntry::tos_state_mask);
3208   __ jcc(Assembler::notZero, notByte);
3209 
3210   // btos
3211   {
3212     __ pop(btos);
3213     if (!is_static) pop_and_check_object(obj);
3214     __ movb(field, rax);
3215     if (!is_static && rc == may_rewrite) {


3242   {
3243     __ pop(atos);
3244     if (!is_static) pop_and_check_object(obj);
3245     // Store into the field
3246     do_oop_store(_masm, field, rax, _bs->kind(), false);
3247     if (!is_static && rc == may_rewrite) {
3248       patch_bytecode(Bytecodes::_fast_aputfield, bc, rbx, true, byte_no);
3249     }
3250     __ jmp(Done);
3251   }
3252 
3253   __ bind(notObj);
3254   __ cmpl(flags, qtos);
3255   __ jcc(Assembler::notEqual, notValueType);
3256 
3257   // qtos
3258   {
3259     __ pop(qtos); // => rax == value
3260     if (!is_static) {
3261       // value types in non-static fields are embedded

3262       pop_and_check_object(rbx);
3263       call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::qputfield),
3264           rbx, rax, flags2);
3265       __ jmp(notVolatile); // value types are never volatile
3266     } else {
3267       // Store into the static field
3268       // Value types in static fields are currently handled with indirection
3269       // but a copy to the Java heap might be required if the value is currently
3270       // stored in a thread local buffer
3271       call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::qputstatic), rax, off, obj);
3272     }
3273     __ jmp(Done);
3274   }
3275 
3276   __ bind(notValueType);
3277   __ cmpl(flags, itos);
3278   __ jcc(Assembler::notEqual, notInt);
3279 
3280   // itos
3281   {
3282     __ pop(itos);
3283     if (!is_static) pop_and_check_object(obj);
3284     __ movl(field, rax);
3285     if (!is_static && rc == may_rewrite) {
3286       patch_bytecode(Bytecodes::_fast_iputfield, bc, rbx, true, byte_no);
3287     }
3288     __ jmp(Done);
3289   }
3290 
3291   __ bind(notInt);


3388 
3389   // dtos
3390   {
3391     __ pop(dtos);
3392     if (!is_static) pop_and_check_object(obj);
3393     __ store_double(field);
3394     if (!is_static && rc == may_rewrite) {
3395       patch_bytecode(Bytecodes::_fast_dputfield, bc, rbx, true, byte_no);
3396     }
3397   }
3398 
3399 #ifdef ASSERT
3400   __ jmp(Done);
3401 
3402   __ bind(notDouble);
3403   __ stop("Bad state");
3404 #endif
3405 
3406   __ bind(Done);
3407 
3408   __ shrl(flags2, ConstantPoolCacheEntry::is_volatile_shift);
3409   __ andl(flags2, 0x1);
3410 
3411   // Check for volatile store
3412   __ testl(flags2, flags2);
3413   __ jcc(Assembler::zero, notVolatile);
3414   volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad |
3415                                                Assembler::StoreStore));
3416   __ bind(notVolatile);
3417 }
3418 
3419 void TemplateTable::putfield(int byte_no) {
3420   putfield_or_static(byte_no, false);
3421 }
3422 
3423 void TemplateTable::nofast_putfield(int byte_no) {
3424   putfield_or_static(byte_no, false, may_not_rewrite);
3425 }
3426 
3427 void TemplateTable::putstatic(int byte_no) {
3428   putfield_or_static(byte_no, true);
3429 }
3430 
3431 void TemplateTable::jvmti_post_fast_field_mod() {
3432 


< prev index next >