Changeset 38652 in webkit for trunk/JavaScriptCore/jit/JIT.cpp
- Timestamp:
- Nov 20, 2008, 9:04:19 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/jit/JIT.cpp
r38600 r38652 531 531 } 532 532 533 JmpSrc JIT::checkStructure(RegisterID reg, Structure* structure) 534 { 535 __ cmpl_i32m(reinterpret_cast<uint32_t>(structure), FIELD_OFFSET(JSCell, m_structure), reg); 536 return __ jne(); 537 } 538 533 539 ALWAYS_INLINE void JIT::emitJumpSlowCaseIfNotJSCell(RegisterID reg, unsigned bytecodeIndex) 534 540 { … … 2352 2358 case op_get_by_id_generic: 2353 2359 case op_get_by_id_proto: 2360 case op_get_by_id_proto_list: 2354 2361 case op_get_by_id_self: 2355 2362 case op_get_string_length: … … 3117 3124 __ testl_i32r(JSImmediate::TagMask, X86::eax); 3118 3125 JmpSrc failureCases1 = __ jne(); 3119 __ cmpl_i32m(reinterpret_cast<uint32_t>(structure), FIELD_OFFSET(JSCell, m_structure), X86::eax); 3120 JmpSrc failureCases2 = __ jne(); 3126 JmpSrc failureCases2 = checkStructure(X86::eax, structure); 3121 3127 3122 3128 // Checks out okay! - getDirectOffset … … 3128 3134 ASSERT(code); 3129 3135 3130 X86Assembler::link(code, failureCases1, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_ fail));3131 X86Assembler::link(code, failureCases2, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_ fail));3136 X86Assembler::link(code, failureCases1, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_self_fail)); 3137 X86Assembler::link(code, failureCases2, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_self_fail)); 3132 3138 3133 3139 m_codeBlock->getStubInfo(returnAddress).stubRoutine = code; … … 3142 3148 3143 3149 // We don't want to repatch more than once - in future go to cti_op_put_by_id_generic. 3144 ctiRepatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_fail)); 3145 3150 #if USE(CTI_REPATCH_PIC) 3151 ctiRepatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_list)); 3152 #else 3153 ctiRepatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_fail)); 3154 #endif 3146 3155 // The prototype object definitely exists (if this stub exists the CodeBlock is referencing a Structure that is 3147 3156 // referencing the prototype object - let's speculatively load it's table nice and early!) … … 3150 3159 __ movl_mr(static_cast<void*>(protoPropertyStorage), X86::edx); 3151 3160 3152 // check eax is an object of the right Structure.3161 // Check eax is an object of the right Structure. 3153 3162 __ testl_i32r(JSImmediate::TagMask, X86::eax); 3154 3163 JmpSrc failureCases1 = __ jne(); 3155 __ cmpl_i32m(reinterpret_cast<uint32_t>(structure), FIELD_OFFSET(JSCell, m_structure), X86::eax); 3156 JmpSrc failureCases2 = __ jne(); 3164 JmpSrc failureCases2 = checkStructure(X86::eax, structure); 3157 3165 3158 3166 // Check the prototype object's Structure had not changed. 3159 3167 Structure** prototypeStructureAddress = &(protoObject->m_structure); 3160 __ cmpl_i32m(reinterpret_cast<uint32_t>(prototypeStructure), static_cast<void*>(prototypeStructureAddress));3168 __ cmpl_i32m(reinterpret_cast<uint32_t>(prototypeStructure), prototypeStructureAddress); 3161 3169 JmpSrc failureCases3 = __ jne(); 3162 3170 … … 3176 3184 3177 3185 // On success return back to the hot patch code, at a point it will perform the store to dest for us. 3178 intptr_t successDest = (intptr_t)(info.hotPathBegin) + repatchOffsetGetByIdPropertyMapOffset;3186 intptr_t successDest = reinterpret_cast<intptr_t>(info.hotPathBegin) + repatchOffsetGetByIdPropertyMapOffset; 3179 3187 X86Assembler::link(code, success, reinterpret_cast<void*>(successDest)); 3180 3188 3181 3189 // Track the stub we have created so that it will be deleted later. 3182 m_codeBlock->getStubInfo(returnAddress).stubRoutine = code; 3183 3184 // Finally repatch the jump to sow case back in the hot path to jump here instead. 3185 // FIXME: should revert this repatching, on failure. 3190 info.stubRoutine = code; 3191 3192 // Finally repatch the jump to slow case back in the hot path to jump here instead. 3186 3193 intptr_t jmpLocation = reinterpret_cast<intptr_t>(info.hotPathBegin) + repatchOffsetGetByIdBranchToSlowCase; 3187 3194 X86Assembler::repatchBranchOffset(jmpLocation, code); … … 3193 3200 __ movl_mr(static_cast<void*>(protoPropertyStorage), X86::edx); 3194 3201 3195 // check eax is an object of the right Structure.3202 // Check eax is an object of the right Structure. 3196 3203 __ testl_i32r(JSImmediate::TagMask, X86::eax); 3197 3204 JmpSrc failureCases1 = __ jne(); 3198 __ cmpl_i32m(reinterpret_cast<uint32_t>(structure), FIELD_OFFSET(JSCell, m_structure), X86::eax); 3199 JmpSrc failureCases2 = __ jne(); 3205 JmpSrc failureCases2 = checkStructure(X86::eax, structure); 3206 3207 // Check the prototype object's Structure had not changed. 3208 Structure** prototypeStructureAddress = &(protoObject->m_structure); 3209 __ cmpl_i32m(reinterpret_cast<uint32_t>(prototypeStructure), prototypeStructureAddress); 3210 JmpSrc failureCases3 = __ jne(); 3211 3212 // Checks out okay! - getDirectOffset 3213 __ movl_mr(cachedOffset * sizeof(JSValue*), X86::edx, X86::eax); 3214 3215 __ ret(); 3216 3217 void* code = __ executableCopy(); 3218 ASSERT(code); 3219 3220 #if USE(CTI_REPATCH_PIC) 3221 X86Assembler::link(code, failureCases1, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_list)); 3222 X86Assembler::link(code, failureCases2, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_list)); 3223 X86Assembler::link(code, failureCases3, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_list)); 3224 #else 3225 X86Assembler::link(code, failureCases1, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_fail)); 3226 X86Assembler::link(code, failureCases2, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_fail)); 3227 X86Assembler::link(code, failureCases3, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_fail)); 3228 #endif 3229 3230 m_codeBlock->getStubInfo(returnAddress).stubRoutine = code; 3231 3232 ctiRepatchCallByReturnAddress(returnAddress, code); 3233 #endif 3234 } 3235 3236 #if USE(CTI_REPATCH_PIC) 3237 void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, PrototypeStructureList* prototypeStructures, int currentIndex, Structure* structure, Structure* prototypeStructure, size_t cachedOffset, CallFrame* callFrame) 3238 { 3239 // The prototype object definitely exists (if this stub exists the CodeBlock is referencing a Structure that is 3240 // referencing the prototype object - let's speculatively load it's table nice and early!) 3241 JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame)); 3242 PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage; 3243 __ movl_mr(static_cast<void*>(protoPropertyStorage), X86::edx); 3244 3245 // Check eax is an object of the right Structure. 3246 __ testl_i32r(JSImmediate::TagMask, X86::eax); 3247 JmpSrc failureCases1 = __ jne(); 3248 JmpSrc failureCases2 = checkStructure(X86::eax, structure); 3200 3249 3201 3250 // Check the prototype object's Structure had not changed. … … 3207 3256 __ movl_mr(cachedOffset * sizeof(JSValue*), X86::edx, X86::eax); 3208 3257 3209 __ ret();3258 JmpSrc success = __ jmp(); 3210 3259 3211 3260 void* code = __ executableCopy(); 3212 3261 ASSERT(code); 3213 3262 3214 X86Assembler::link(code, failureCases1, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_fail)); 3215 X86Assembler::link(code, failureCases2, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_fail)); 3216 X86Assembler::link(code, failureCases3, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_fail)); 3217 3218 m_codeBlock->getStubInfo(returnAddress).stubRoutine = code; 3219 3220 ctiRepatchCallByReturnAddress(returnAddress, code); 3263 // Use the repatch information to link the failure cases back to the original slow case routine. 3264 void* lastProtoBegin = prototypeStructures->list[currentIndex - 1].stubRoutine; 3265 X86Assembler::link(code, failureCases1, lastProtoBegin); 3266 X86Assembler::link(code, failureCases2, lastProtoBegin); 3267 X86Assembler::link(code, failureCases3, lastProtoBegin); 3268 3269 // On success return back to the hot patch code, at a point it will perform the store to dest for us. 3270 intptr_t successDest = reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + repatchOffsetGetByIdPropertyMapOffset; 3271 X86Assembler::link(code, success, reinterpret_cast<void*>(successDest)); 3272 3273 structure->ref(); 3274 prototypeStructure->ref(); 3275 prototypeStructures->list[currentIndex].set(structure, prototypeStructure, cachedOffset, code); 3276 3277 // Finally repatch the jump to slow case back in the hot path to jump here instead. 3278 intptr_t jmpLocation = reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + repatchOffsetGetByIdBranchToSlowCase; 3279 X86Assembler::repatchBranchOffset(jmpLocation, code); 3280 } 3221 3281 #endif 3222 }3223 3282 3224 3283 void JIT::privateCompileGetByIdChain(Structure* structure, StructureChain* chain, size_t count, size_t cachedOffset, void* returnAddress, CallFrame* callFrame) … … 3230 3289 // Check eax is an object of the right Structure. 3231 3290 __ testl_i32r(JSImmediate::TagMask, X86::eax); 3232 bucketsOfFail.append(__ jne()); 3233 __ cmpl_i32m(reinterpret_cast<uint32_t>(structure), FIELD_OFFSET(JSCell, m_structure), X86::eax); 3234 bucketsOfFail.append(__ jne()); 3291 bucketsOfFail.append(checkStructure(X86::eax, structure)); 3235 3292 3236 3293 Structure* currStructure = structure; … … 3259 3316 3260 3317 for (unsigned i = 0; i < bucketsOfFail.size(); ++i) 3261 X86Assembler::link(code, bucketsOfFail[i], reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_ fail));3318 X86Assembler::link(code, bucketsOfFail[i], reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_chain_fail)); 3262 3319 3263 3320 m_codeBlock->getStubInfo(returnAddress).stubRoutine = code; … … 3268 3325 void JIT::privateCompilePutByIdReplace(Structure* structure, size_t cachedOffset, void* returnAddress) 3269 3326 { 3270 // check eax is an object of the right Structure.3327 // Check eax is an object of the right Structure. 3271 3328 __ testl_i32r(JSImmediate::TagMask, X86::eax); 3272 3329 JmpSrc failureCases1 = __ jne(); 3273 __ cmpl_i32m(reinterpret_cast<uint32_t>(structure), FIELD_OFFSET(JSCell, m_structure), X86::eax); 3274 JmpSrc failureCases2 = __ jne(); 3330 JmpSrc failureCases2 = checkStructure(X86::eax, structure); 3275 3331 3276 3332 // checks out okay! - putDirectOffset … … 3308 3364 { 3309 3365 Vector<JmpSrc, 16> failureCases; 3310 // check eax is an object of the right Structure.3366 // Check eax is an object of the right Structure. 3311 3367 __ testl_i32r(JSImmediate::TagMask, X86::eax); 3312 3368 failureCases.append(__ jne()); … … 3428 3484 __ movl_mr(FIELD_OFFSET(ArrayStorage, m_length), X86::eax, X86::eax); 3429 3485 3486 __ cmpl_i32r(JSImmediate::maxImmediateInt, X86::eax); 3487 JmpSrc array_failureCases3 = __ ja(); 3488 3430 3489 __ addl_rr(X86::eax, X86::eax); 3431 JmpSrc array_failureCases3 = __ jo();3432 3490 __ addl_i8r(1, X86::eax); 3433 3491 … … 3448 3506 __ movl_mr(FIELD_OFFSET(UString::Rep, len), X86::eax, X86::eax); 3449 3507 3508 __ cmpl_i32r(JSImmediate::maxImmediateInt, X86::eax); 3509 JmpSrc string_failureCases3 = __ ja(); 3510 3450 3511 __ addl_rr(X86::eax, X86::eax); 3451 JmpSrc string_failureCases3 = __ jo();3452 3512 __ addl_i8r(1, X86::eax); 3453 3513 … … 3583 3643 ASSERT(code); 3584 3644 3585 X86Assembler::link(code, array_failureCases1, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_ fail));3586 X86Assembler::link(code, array_failureCases2, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_ fail));3587 X86Assembler::link(code, array_failureCases3, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_ fail));3588 X86Assembler::link(code, string_failureCases1, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_ fail));3589 X86Assembler::link(code, string_failureCases2, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_ fail));3590 X86Assembler::link(code, string_failureCases3, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_ fail));3645 X86Assembler::link(code, array_failureCases1, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_array_fail)); 3646 X86Assembler::link(code, array_failureCases2, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_array_fail)); 3647 X86Assembler::link(code, array_failureCases3, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_array_fail)); 3648 X86Assembler::link(code, string_failureCases1, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_string_fail)); 3649 X86Assembler::link(code, string_failureCases2, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_string_fail)); 3650 X86Assembler::link(code, string_failureCases3, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_string_fail)); 3591 3651 X86Assembler::link(code, callArityCheck1, reinterpret_cast<void*>(Interpreter::cti_op_call_arityCheck)); 3592 3652 X86Assembler::link(code, callArityCheck2, reinterpret_cast<void*>(Interpreter::cti_op_call_arityCheck)); … … 3641 3701 3642 3702 // We don't want to repatch more than once - in future go to cti_op_put_by_id_generic. 3643 ctiRepatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_ fail));3703 ctiRepatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_array_fail)); 3644 3704 3645 3705 // Check eax is an array … … 3671 3731 3672 3732 // On success return back to the hot patch code, at a point it will perform the store to dest for us. 3673 intptr_t successDest = (intptr_t)(info.hotPathBegin) + repatchOffsetGetByIdPropertyMapOffset;3733 intptr_t successDest = reinterpret_cast<intptr_t>(info.hotPathBegin) + repatchOffsetGetByIdPropertyMapOffset; 3674 3734 X86Assembler::link(code, success, reinterpret_cast<void*>(successDest)); 3675 3735 … … 3678 3738 3679 3739 // Finally repatch the jump to sow case back in the hot path to jump here instead. 3680 // FIXME: should revert this repatching, on failure.3681 3740 intptr_t jmpLocation = reinterpret_cast<intptr_t>(info.hotPathBegin) + repatchOffsetGetByIdBranchToSlowCase; 3682 3741 X86Assembler::repatchBranchOffset(jmpLocation, code);
Note:
See TracChangeset
for help on using the changeset viewer.