| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 729 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 740 code = masm->isolate()->builtins()->builtin(Builtins::kLoadIC_Miss); | 740 code = masm->isolate()->builtins()->builtin(Builtins::kLoadIC_Miss); |
| 741 } else { | 741 } else { |
| 742 code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss); | 742 code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss); |
| 743 } | 743 } |
| 744 | 744 |
| 745 Handle<Code> ic(code); | 745 Handle<Code> ic(code); |
| 746 __ Jump(ic, RelocInfo::CODE_TARGET); | 746 __ Jump(ic, RelocInfo::CODE_TARGET); |
| 747 } | 747 } |
| 748 | 748 |
| 749 | 749 |
| 750 void StubCompiler::GenerateKeyedLoadMissForceGeneric(MacroAssembler* masm) { |
| 751 Code* code = masm->isolate()->builtins()->builtin( |
| 752 Builtins::kKeyedLoadIC_MissForceGeneric); |
| 753 Handle<Code> ic(code); |
| 754 __ Jump(ic, RelocInfo::CODE_TARGET); |
| 755 } |
| 756 |
| 757 |
| 750 // Both name_reg and receiver_reg are preserved on jumps to miss_label, | 758 // Both name_reg and receiver_reg are preserved on jumps to miss_label, |
| 751 // but may be destroyed if store is successful. | 759 // but may be destroyed if store is successful. |
| 752 void StubCompiler::GenerateStoreField(MacroAssembler* masm, | 760 void StubCompiler::GenerateStoreField(MacroAssembler* masm, |
| 753 JSObject* object, | 761 JSObject* object, |
| 754 int index, | 762 int index, |
| 755 Map* transition, | 763 Map* transition, |
| 756 Register receiver_reg, | 764 Register receiver_reg, |
| 757 Register name_reg, | 765 Register name_reg, |
| 758 Register scratch, | 766 Register scratch, |
| 759 Label* miss_label) { | 767 Label* miss_label) { |
| (...skipping 1756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2516 __ bind(&miss); | 2524 __ bind(&miss); |
| 2517 __ DecrementCounter(counters->keyed_store_field(), 1); | 2525 __ DecrementCounter(counters->keyed_store_field(), 1); |
| 2518 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); | 2526 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); |
| 2519 __ Jump(ic, RelocInfo::CODE_TARGET); | 2527 __ Jump(ic, RelocInfo::CODE_TARGET); |
| 2520 | 2528 |
| 2521 // Return the generated code. | 2529 // Return the generated code. |
| 2522 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); | 2530 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); |
| 2523 } | 2531 } |
| 2524 | 2532 |
| 2525 | 2533 |
| 2526 MaybeObject* KeyedStoreStubCompiler::CompileStoreSpecialized( | 2534 MaybeObject* KeyedStoreStubCompiler::CompileStoreSpecialized(Handle<Map> receive
r_map) { |
| 2527 JSObject* receiver) { | |
| 2528 // ----------- S t a t e ------------- | 2535 // ----------- S t a t e ------------- |
| 2529 // -- rax : value | 2536 // -- rax : value |
| 2530 // -- rcx : key | 2537 // -- rcx : key |
| 2531 // -- rdx : receiver | 2538 // -- rdx : receiver |
| 2532 // -- rsp[0] : return address | 2539 // -- rsp[0] : return address |
| 2533 // ----------------------------------- | 2540 // ----------------------------------- |
| 2534 Label miss; | 2541 Label miss, miss_force_generic; |
| 2535 | 2542 |
| 2536 // Check that the receiver isn't a smi. | 2543 __ CheckMap(rdx, receiver_map, &miss, false); |
| 2537 __ JumpIfSmi(rdx, &miss); | |
| 2538 | |
| 2539 // Check that the map matches. | |
| 2540 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), | |
| 2541 Handle<Map>(receiver->map())); | |
| 2542 __ j(not_equal, &miss); | |
| 2543 | 2544 |
| 2544 // Check that the key is a smi. | 2545 // Check that the key is a smi. |
| 2545 __ JumpIfNotSmi(rcx, &miss); | 2546 __ JumpIfNotSmi(rcx, &miss_force_generic); |
| 2546 | 2547 |
| 2547 // Get the elements array and make sure it is a fast element array, not 'cow'. | 2548 // Get the elements array and make sure it is a fast element array, not 'cow'. |
| 2548 __ movq(rdi, FieldOperand(rdx, JSObject::kElementsOffset)); | 2549 __ movq(rdi, FieldOperand(rdx, JSObject::kElementsOffset)); |
| 2549 __ Cmp(FieldOperand(rdi, HeapObject::kMapOffset), | 2550 __ Cmp(FieldOperand(rdi, HeapObject::kMapOffset), |
| 2550 factory()->fixed_array_map()); | 2551 factory()->fixed_array_map()); |
| 2551 __ j(not_equal, &miss); | 2552 __ j(not_equal, &miss_force_generic); |
| 2552 | 2553 |
| 2553 // Check that the key is within bounds. | 2554 // Check that the key is within bounds. |
| 2554 if (receiver->IsJSArray()) { | 2555 if (receiver_map->instance_type() == JS_ARRAY_TYPE) { |
| 2555 __ SmiCompare(rcx, FieldOperand(rdx, JSArray::kLengthOffset)); | 2556 __ SmiCompare(rcx, FieldOperand(rdx, JSArray::kLengthOffset)); |
| 2556 __ j(above_equal, &miss); | 2557 __ j(above_equal, &miss_force_generic); |
| 2557 } else { | 2558 } else { |
| 2558 __ SmiCompare(rcx, FieldOperand(rdi, FixedArray::kLengthOffset)); | 2559 __ SmiCompare(rcx, FieldOperand(rdi, FixedArray::kLengthOffset)); |
| 2559 __ j(above_equal, &miss); | 2560 __ j(above_equal, &miss_force_generic); |
| 2560 } | 2561 } |
| 2561 | 2562 |
| 2562 // Do the store and update the write barrier. Make sure to preserve | 2563 // Do the store and update the write barrier. Make sure to preserve |
| 2563 // the value in register eax. | 2564 // the value in register eax. |
| 2564 __ movq(rdx, rax); | 2565 __ movq(rdx, rax); |
| 2565 __ SmiToInteger32(rcx, rcx); | 2566 __ SmiToInteger32(rcx, rcx); |
| 2566 __ movq(FieldOperand(rdi, rcx, times_pointer_size, FixedArray::kHeaderSize), | 2567 __ movq(FieldOperand(rdi, rcx, times_pointer_size, FixedArray::kHeaderSize), |
| 2567 rax); | 2568 rax); |
| 2568 __ RecordWrite(rdi, 0, rdx, rcx); | 2569 __ RecordWrite(rdi, 0, rdx, rcx); |
| 2569 | 2570 |
| 2570 // Done. | 2571 // Done. |
| 2571 __ ret(0); | 2572 __ ret(0); |
| 2572 | 2573 |
| 2573 // Handle store cache miss. | 2574 // Handle store cache miss. |
| 2574 __ bind(&miss); | 2575 __ bind(&miss); |
| 2575 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); | 2576 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); |
| 2576 __ jmp(ic, RelocInfo::CODE_TARGET); | 2577 __ jmp(ic, RelocInfo::CODE_TARGET); |
| 2577 | 2578 |
| 2579 // Handle store cache miss. |
| 2580 __ bind(&miss_force_generic); |
| 2581 Handle<Code> ic_force_generic = |
| 2582 isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); |
| 2583 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); |
| 2584 |
| 2578 // Return the generated code. | 2585 // Return the generated code. |
| 2579 return GetCode(NORMAL, NULL); | 2586 return GetCode(NORMAL, NULL); |
| 2580 } | 2587 } |
| 2581 | 2588 |
| 2582 | 2589 |
| 2590 MaybeObject* KeyedStoreStubCompiler::CompileStoreMegamorphic( |
| 2591 ZoneMapList* receiver_maps, |
| 2592 ZoneCodeList* handler_ics) { |
| 2593 // ----------- S t a t e ------------- |
| 2594 // -- rax : receiver |
| 2595 // -- rcx : name |
| 2596 // -- rsp[0] : return address |
| 2597 // ----------------------------------- |
| 2598 Label miss; |
| 2599 __ JumpIfSmi(rax, &miss); |
| 2600 |
| 2601 int receiver_count = receiver_maps->length(); |
| 2602 for (int current = 0; current < receiver_count; ++current) { |
| 2603 // Check map and tail call if there's a match |
| 2604 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), receiver_maps->at(current)
); |
| 2605 __ j(equal, handler_ics->at(current), RelocInfo::CODE_TARGET); |
| 2606 } |
| 2607 __ bind(&miss); |
| 2608 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); |
| 2609 __ jmp(ic, RelocInfo::CODE_TARGET); |
| 2610 |
| 2611 // Return the generated code. |
| 2612 return GetCode(NORMAL, NULL, MEGAMORPHIC); |
| 2613 } |
| 2614 |
| 2615 |
| 2583 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, | 2616 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, |
| 2584 JSObject* object, | 2617 JSObject* object, |
| 2585 JSObject* last) { | 2618 JSObject* last) { |
| 2586 // ----------- S t a t e ------------- | 2619 // ----------- S t a t e ------------- |
| 2587 // -- rax : receiver | 2620 // -- rax : receiver |
| 2588 // -- rcx : name | 2621 // -- rcx : name |
| 2589 // -- rsp[0] : return address | 2622 // -- rsp[0] : return address |
| 2590 // ----------------------------------- | 2623 // ----------------------------------- |
| 2591 Label miss; | 2624 Label miss; |
| 2592 | 2625 |
| 2593 // Chech that receiver is not a smi. | 2626 // Check that receiver is not a smi. |
| 2594 __ JumpIfSmi(rax, &miss); | 2627 __ JumpIfSmi(rax, &miss); |
| 2595 | 2628 |
| 2596 // Check the maps of the full prototype chain. Also check that | 2629 // Check the maps of the full prototype chain. Also check that |
| 2597 // global property cells up to (but not including) the last object | 2630 // global property cells up to (but not including) the last object |
| 2598 // in the prototype chain are empty. | 2631 // in the prototype chain are empty. |
| 2599 CheckPrototypes(object, rax, last, rbx, rdx, rdi, name, &miss); | 2632 CheckPrototypes(object, rax, last, rbx, rdx, rdi, name, &miss); |
| 2600 | 2633 |
| 2601 // If the last object in the prototype chain is a global object, | 2634 // If the last object in the prototype chain is a global object, |
| 2602 // check that the global property cell is empty. | 2635 // check that the global property cell is empty. |
| 2603 if (last->IsGlobalObject()) { | 2636 if (last->IsGlobalObject()) { |
| (...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2974 GenerateLoadFunctionPrototype(masm(), rdx, rcx, rbx, &miss); | 3007 GenerateLoadFunctionPrototype(masm(), rdx, rcx, rbx, &miss); |
| 2975 __ bind(&miss); | 3008 __ bind(&miss); |
| 2976 __ DecrementCounter(counters->keyed_load_function_prototype(), 1); | 3009 __ DecrementCounter(counters->keyed_load_function_prototype(), 1); |
| 2977 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3010 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 2978 | 3011 |
| 2979 // Return the generated code. | 3012 // Return the generated code. |
| 2980 return GetCode(CALLBACKS, name); | 3013 return GetCode(CALLBACKS, name); |
| 2981 } | 3014 } |
| 2982 | 3015 |
| 2983 | 3016 |
| 2984 MaybeObject* KeyedLoadStubCompiler::CompileLoadSpecialized(JSObject* receiver) { | 3017 MaybeObject* KeyedLoadStubCompiler::CompileLoadSpecialized(Handle<Map> receiver_
map) { |
| 2985 // ----------- S t a t e ------------- | 3018 // ----------- S t a t e ------------- |
| 2986 // -- rax : key | 3019 // -- rax : key |
| 2987 // -- rdx : receiver | 3020 // -- rdx : receiver |
| 2988 // -- rsp[0] : return address | 3021 // -- rsp[0] : return address |
| 2989 // ----------------------------------- | 3022 // ----------------------------------- |
| 2990 Label miss; | 3023 Label miss, miss_force_generic; |
| 2991 | 3024 |
| 2992 // Check that the receiver isn't a smi. | 3025 __ CheckMap(rdx, receiver_map, &miss, false); |
| 2993 __ JumpIfSmi(rdx, &miss); | |
| 2994 | |
| 2995 // Check that the map matches. | |
| 2996 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), | |
| 2997 Handle<Map>(receiver->map())); | |
| 2998 __ j(not_equal, &miss); | |
| 2999 | 3026 |
| 3000 // Check that the key is a smi. | 3027 // Check that the key is a smi. |
| 3001 __ JumpIfNotSmi(rax, &miss); | 3028 __ JumpIfNotSmi(rax, &miss_force_generic); |
| 3002 | 3029 |
| 3003 // Get the elements array. | 3030 // Get the elements array. |
| 3004 __ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset)); | 3031 __ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset)); |
| 3005 __ AssertFastElements(rcx); | 3032 __ AssertFastElements(rcx); |
| 3006 | 3033 |
| 3007 // Check that the key is within bounds. | 3034 // Check that the key is within bounds. |
| 3008 __ SmiCompare(rax, FieldOperand(rcx, FixedArray::kLengthOffset)); | 3035 __ SmiCompare(rax, FieldOperand(rcx, FixedArray::kLengthOffset)); |
| 3009 __ j(above_equal, &miss); | 3036 __ j(above_equal, &miss_force_generic); |
| 3010 | 3037 |
| 3011 // Load the result and make sure it's not the hole. | 3038 // Load the result and make sure it's not the hole. |
| 3012 SmiIndex index = masm()->SmiToIndex(rbx, rax, kPointerSizeLog2); | 3039 SmiIndex index = masm()->SmiToIndex(rbx, rax, kPointerSizeLog2); |
| 3013 __ movq(rbx, FieldOperand(rcx, | 3040 __ movq(rbx, FieldOperand(rcx, |
| 3014 index.reg, | 3041 index.reg, |
| 3015 index.scale, | 3042 index.scale, |
| 3016 FixedArray::kHeaderSize)); | 3043 FixedArray::kHeaderSize)); |
| 3017 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); | 3044 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); |
| 3018 __ j(equal, &miss); | 3045 __ j(equal, &miss_force_generic); |
| 3019 __ movq(rax, rbx); | 3046 __ movq(rax, rbx); |
| 3020 __ ret(0); | 3047 __ ret(0); |
| 3021 | 3048 |
| 3022 __ bind(&miss); | 3049 __ bind(&miss); |
| 3023 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3050 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 3024 | 3051 |
| 3052 __ bind(&miss_force_generic); |
| 3053 GenerateKeyedLoadMissForceGeneric(masm()); |
| 3054 |
| 3025 // Return the generated code. | 3055 // Return the generated code. |
| 3026 return GetCode(NORMAL, NULL); | 3056 return GetCode(NORMAL, NULL); |
| 3027 } | 3057 } |
| 3028 | 3058 |
| 3029 | 3059 |
| 3060 MaybeObject* KeyedLoadStubCompiler::CompileLoadMegamorphic( |
| 3061 ZoneMapList* receiver_maps, |
| 3062 ZoneCodeList* handler_ics) { |
| 3063 // ----------- S t a t e ------------- |
| 3064 // -- rax : key |
| 3065 // -- rdx : receiver |
| 3066 // -- rsp[0] : return address |
| 3067 // ----------------------------------- |
| 3068 Label miss; |
| 3069 |
| 3070 __ JumpIfSmi(rax, &miss); |
| 3071 |
| 3072 int receiver_count = receiver_maps->length(); |
| 3073 for (int current = 0; current < receiver_count; ++current) { |
| 3074 // Check map and tail call if there's a match |
| 3075 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), receiver_maps->at(current)
); |
| 3076 __ j(equal, handler_ics->at(current), RelocInfo::CODE_TARGET); |
| 3077 } |
| 3078 __ bind(&miss); |
| 3079 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 3080 |
| 3081 // Return the generated code. |
| 3082 return GetCode(NORMAL, NULL, MEGAMORPHIC); |
| 3083 } |
| 3084 |
| 3085 |
| 3030 // Specialized stub for constructing objects from functions which only have only | 3086 // Specialized stub for constructing objects from functions which only have only |
| 3031 // simple assignments of the form this.x = ...; in their body. | 3087 // simple assignments of the form this.x = ...; in their body. |
| 3032 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { | 3088 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { |
| 3033 // ----------- S t a t e ------------- | 3089 // ----------- S t a t e ------------- |
| 3034 // -- rax : argc | 3090 // -- rax : argc |
| 3035 // -- rdi : constructor | 3091 // -- rdi : constructor |
| 3036 // -- rsp[0] : return address | 3092 // -- rsp[0] : return address |
| 3037 // -- rsp[4] : last argument | 3093 // -- rsp[4] : last argument |
| 3038 // ----------------------------------- | 3094 // ----------------------------------- |
| 3039 Label generic_stub_call; | 3095 Label generic_stub_call; |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3160 } | 3216 } |
| 3161 | 3217 |
| 3162 | 3218 |
| 3163 MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub( | 3219 MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub( |
| 3164 JSObject* receiver, ExternalArrayType array_type, Code::Flags flags) { | 3220 JSObject* receiver, ExternalArrayType array_type, Code::Flags flags) { |
| 3165 // ----------- S t a t e ------------- | 3221 // ----------- S t a t e ------------- |
| 3166 // -- rax : key | 3222 // -- rax : key |
| 3167 // -- rdx : receiver | 3223 // -- rdx : receiver |
| 3168 // -- rsp[0] : return address | 3224 // -- rsp[0] : return address |
| 3169 // ----------------------------------- | 3225 // ----------------------------------- |
| 3170 Label slow; | 3226 Label slow, miss; |
| 3171 | 3227 |
| 3172 // Check that the object isn't a smi. | 3228 // Check that the object isn't a smi. |
| 3173 __ JumpIfSmi(rdx, &slow); | 3229 __ JumpIfSmi(rdx, &miss); |
| 3174 | 3230 |
| 3175 // Check that the key is a smi. | 3231 // Check that the key is a smi. |
| 3176 __ JumpIfNotSmi(rax, &slow); | 3232 __ JumpIfNotSmi(rax, &miss); |
| 3177 | 3233 |
| 3178 // Check that the map matches. | 3234 // Check that the map matches. |
| 3179 __ CheckMap(rdx, Handle<Map>(receiver->map()), &slow, false); | 3235 __ CheckMap(rdx, Handle<Map>(receiver->map()), &miss, false); |
| 3180 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); | 3236 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); |
| 3181 | 3237 |
| 3182 // Check that the index is in range. | 3238 // Check that the index is in range. |
| 3183 __ SmiToInteger32(rcx, rax); | 3239 __ SmiToInteger32(rcx, rax); |
| 3184 __ cmpl(rcx, FieldOperand(rbx, ExternalArray::kLengthOffset)); | 3240 __ cmpl(rcx, FieldOperand(rbx, ExternalArray::kLengthOffset)); |
| 3185 // Unsigned comparison catches both negative and too-large values. | 3241 // Unsigned comparison catches both negative and too-large values. |
| 3186 __ j(above_equal, &slow); | 3242 __ j(above_equal, &miss); |
| 3187 | 3243 |
| 3188 // rax: index (as a smi) | 3244 // rax: index (as a smi) |
| 3189 // rdx: receiver (JSObject) | 3245 // rdx: receiver (JSObject) |
| 3190 // rcx: untagged index | 3246 // rcx: untagged index |
| 3191 // rbx: elements array | 3247 // rbx: elements array |
| 3192 __ movq(rbx, FieldOperand(rbx, ExternalArray::kExternalPointerOffset)); | 3248 __ movq(rbx, FieldOperand(rbx, ExternalArray::kExternalPointerOffset)); |
| 3193 // rbx: base pointer of external storage | 3249 // rbx: base pointer of external storage |
| 3194 switch (array_type) { | 3250 switch (array_type) { |
| 3195 case kExternalByteArray: | 3251 case kExternalByteArray: |
| 3196 __ movsxbq(rcx, Operand(rbx, rcx, times_1, 0)); | 3252 __ movsxbq(rcx, Operand(rbx, rcx, times_1, 0)); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3272 __ bind(&slow); | 3328 __ bind(&slow); |
| 3273 Counters* counters = isolate()->counters(); | 3329 Counters* counters = isolate()->counters(); |
| 3274 __ IncrementCounter(counters->keyed_load_external_array_slow(), 1); | 3330 __ IncrementCounter(counters->keyed_load_external_array_slow(), 1); |
| 3275 | 3331 |
| 3276 // ----------- S t a t e ------------- | 3332 // ----------- S t a t e ------------- |
| 3277 // -- rax : key | 3333 // -- rax : key |
| 3278 // -- rdx : receiver | 3334 // -- rdx : receiver |
| 3279 // -- rsp[0] : return address | 3335 // -- rsp[0] : return address |
| 3280 // ----------------------------------- | 3336 // ----------------------------------- |
| 3281 | 3337 |
| 3282 __ pop(rbx); | 3338 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Slow(); |
| 3283 __ push(rdx); // receiver | 3339 __ jmp(ic, RelocInfo::CODE_TARGET); |
| 3284 __ push(rax); // name | |
| 3285 __ push(rbx); // return address | |
| 3286 | 3340 |
| 3287 // Perform tail call to the entry. | 3341 // Slow case: Jump to runtime. |
| 3288 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); | 3342 __ bind(&miss); |
| 3343 // ----------- S t a t e ------------- |
| 3344 // -- rax : key |
| 3345 // -- rdx : receiver |
| 3346 // -- rsp[0] : return address |
| 3347 // ----------------------------------- |
| 3348 |
| 3349 Handle<Code> miss_ic = isolate()->builtins()->KeyedLoadIC_Miss(); |
| 3350 __ jmp(miss_ic, RelocInfo::CODE_TARGET); |
| 3289 | 3351 |
| 3290 // Return the generated code. | 3352 // Return the generated code. |
| 3291 return GetCode(flags); | 3353 return GetCode(flags); |
| 3292 } | 3354 } |
| 3293 | 3355 |
| 3294 | 3356 |
| 3295 MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub( | 3357 MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub( |
| 3296 JSObject* receiver, ExternalArrayType array_type, Code::Flags flags) { | 3358 JSObject* receiver, ExternalArrayType array_type, Code::Flags flags) { |
| 3297 // ----------- S t a t e ------------- | 3359 // ----------- S t a t e ------------- |
| 3298 // -- rax : value | 3360 // -- rax : value |
| 3299 // -- rcx : key | 3361 // -- rcx : key |
| 3300 // -- rdx : receiver | 3362 // -- rdx : receiver |
| 3301 // -- rsp[0] : return address | 3363 // -- rsp[0] : return address |
| 3302 // ----------------------------------- | 3364 // ----------------------------------- |
| 3303 Label slow; | 3365 Label slow, miss; |
| 3366 |
| 3367 // Check that the key is a smi. |
| 3368 __ JumpIfNotSmi(rcx, &miss); |
| 3304 | 3369 |
| 3305 // Check that the object isn't a smi. | 3370 // Check that the object isn't a smi. |
| 3306 __ JumpIfSmi(rdx, &slow); | 3371 __ JumpIfSmi(rdx, &miss); |
| 3307 | 3372 |
| 3308 // Check that the map matches. | 3373 // Check that the map matches. |
| 3309 __ CheckMap(rdx, Handle<Map>(receiver->map()), &slow, false); | 3374 __ CheckMap(rdx, Handle<Map>(receiver->map()), &miss, false); |
| 3310 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); | 3375 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); |
| 3311 | 3376 |
| 3312 // Check that the key is a smi. | 3377 // Check that the key is a smi. |
| 3313 __ JumpIfNotSmi(rcx, &slow); | 3378 __ JumpIfNotSmi(rcx, &miss); |
| 3314 | 3379 |
| 3315 // Check that the index is in range. | 3380 // Check that the index is in range. |
| 3316 __ SmiToInteger32(rdi, rcx); // Untag the index. | 3381 __ SmiToInteger32(rdi, rcx); // Untag the index. |
| 3317 __ cmpl(rdi, FieldOperand(rbx, ExternalArray::kLengthOffset)); | 3382 __ cmpl(rdi, FieldOperand(rbx, ExternalArray::kLengthOffset)); |
| 3318 // Unsigned comparison catches both negative and too-large values. | 3383 // Unsigned comparison catches both negative and too-large values. |
| 3319 __ j(above_equal, &slow); | 3384 __ j(above_equal, &miss); |
| 3320 | 3385 |
| 3321 // Handle both smis and HeapNumbers in the fast path. Go to the | 3386 // Handle both smis and HeapNumbers in the fast path. Go to the |
| 3322 // runtime for all other kinds of values. | 3387 // runtime for all other kinds of values. |
| 3323 // rax: value | 3388 // rax: value |
| 3324 // rcx: key (a smi) | 3389 // rcx: key (a smi) |
| 3325 // rdx: receiver (a JSObject) | 3390 // rdx: receiver (a JSObject) |
| 3326 // rbx: elements array | 3391 // rbx: elements array |
| 3327 // rdi: untagged key | 3392 // rdi: untagged key |
| 3328 NearLabel check_heap_number; | 3393 NearLabel check_heap_number; |
| 3329 if (array_type == kExternalPixelArray) { | 3394 if (array_type == kExternalPixelArray) { |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3443 // Slow case: call runtime. | 3508 // Slow case: call runtime. |
| 3444 __ bind(&slow); | 3509 __ bind(&slow); |
| 3445 | 3510 |
| 3446 // ----------- S t a t e ------------- | 3511 // ----------- S t a t e ------------- |
| 3447 // -- rax : value | 3512 // -- rax : value |
| 3448 // -- rcx : key | 3513 // -- rcx : key |
| 3449 // -- rdx : receiver | 3514 // -- rdx : receiver |
| 3450 // -- rsp[0] : return address | 3515 // -- rsp[0] : return address |
| 3451 // ----------------------------------- | 3516 // ----------------------------------- |
| 3452 | 3517 |
| 3453 __ pop(rbx); | 3518 bool strict = (Code::ExtractExtraICStateFromFlags(flags) & kStrictMode) != 0; |
| 3454 __ push(rdx); // receiver | 3519 Handle<Code> ic = strict |
| 3455 __ push(rcx); // key | 3520 ? isolate()->builtins()->KeyedStoreIC_Slow_Strict() |
| 3456 __ push(rax); // value | 3521 : isolate()->builtins()->KeyedStoreIC_Slow_NonStrict(); |
| 3457 __ Push(Smi::FromInt(NONE)); // PropertyAttributes | 3522 __ jmp(ic, RelocInfo::CODE_TARGET); |
| 3458 __ Push(Smi::FromInt( | |
| 3459 Code::ExtractExtraICStateFromFlags(flags) & kStrictMode)); | |
| 3460 __ push(rbx); // return address | |
| 3461 | 3523 |
| 3462 // Do tail-call to runtime routine. | 3524 // Miss case: call runtime. |
| 3463 __ TailCallRuntime(Runtime::kSetProperty, 5, 1); | 3525 __ bind(&miss); |
| 3526 |
| 3527 // ----------- S t a t e ------------- |
| 3528 // -- rax : value |
| 3529 // -- rcx : key |
| 3530 // -- rdx : receiver |
| 3531 // -- rsp[0] : return address |
| 3532 // ----------------------------------- |
| 3533 |
| 3534 Handle<Code> miss_ic = isolate()->builtins()->KeyedStoreIC_Miss(); |
| 3535 __ jmp(miss_ic, RelocInfo::CODE_TARGET); |
| 3464 | 3536 |
| 3465 return GetCode(flags); | 3537 return GetCode(flags); |
| 3466 } | 3538 } |
| 3467 | 3539 |
| 3468 #undef __ | 3540 #undef __ |
| 3469 | 3541 |
| 3470 } } // namespace v8::internal | 3542 } } // namespace v8::internal |
| 3471 | 3543 |
| 3472 #endif // V8_TARGET_ARCH_X64 | 3544 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |