Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(162)

Side by Side Diff: src/ia32/stub-cache-ia32.cc

Issue 6894003: Better support for 'polymorphic' JS and external arrays (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: new strategy Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 740 matching lines...) Expand 10 before | Expand all | Expand 10 after
751 code = masm->isolate()->builtins()->builtin(Builtins::kLoadIC_Miss); 751 code = masm->isolate()->builtins()->builtin(Builtins::kLoadIC_Miss);
752 } else { 752 } else {
753 code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss); 753 code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss);
754 } 754 }
755 755
756 Handle<Code> ic(code); 756 Handle<Code> ic(code);
757 __ jmp(ic, RelocInfo::CODE_TARGET); 757 __ jmp(ic, RelocInfo::CODE_TARGET);
758 } 758 }
759 759
760 760
761 void StubCompiler::GenerateKeyedLoadMissForceGeneric(MacroAssembler* masm) {
762 Code* code = masm->isolate()->builtins()->builtin(
763 Builtins::kKeyedLoadIC_MissForceGeneric);
Mads Ager (chromium) 2011/04/28 13:02:01 Four space indent?
764 Handle<Code> ic(code);
765 __ jmp(ic, RelocInfo::CODE_TARGET);
766 }
767
768
761 // Both name_reg and receiver_reg are preserved on jumps to miss_label, 769 // Both name_reg and receiver_reg are preserved on jumps to miss_label,
762 // but may be destroyed if store is successful. 770 // but may be destroyed if store is successful.
763 void StubCompiler::GenerateStoreField(MacroAssembler* masm, 771 void StubCompiler::GenerateStoreField(MacroAssembler* masm,
764 JSObject* object, 772 JSObject* object,
765 int index, 773 int index,
766 Map* transition, 774 Map* transition,
767 Register receiver_reg, 775 Register receiver_reg,
768 Register name_reg, 776 Register name_reg,
769 Register scratch, 777 Register scratch,
770 Label* miss_label) { 778 Label* miss_label) {
(...skipping 1916 matching lines...) Expand 10 before | Expand all | Expand 10 after
2687 __ bind(&miss); 2695 __ bind(&miss);
2688 __ DecrementCounter(counters->keyed_store_field(), 1); 2696 __ DecrementCounter(counters->keyed_store_field(), 1);
2689 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); 2697 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
2690 __ jmp(ic, RelocInfo::CODE_TARGET); 2698 __ jmp(ic, RelocInfo::CODE_TARGET);
2691 2699
2692 // Return the generated code. 2700 // Return the generated code.
2693 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); 2701 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name);
2694 } 2702 }
2695 2703
2696 2704
2697 MaybeObject* KeyedStoreStubCompiler::CompileStoreSpecialized( 2705 MaybeObject* KeyedStoreStubCompiler::CompileStoreSpecialized(Handle<Map> receive r_map) {
2698 JSObject* receiver) {
2699 // ----------- S t a t e ------------- 2706 // ----------- S t a t e -------------
2700 // -- eax : value 2707 // -- eax : value
2701 // -- ecx : key 2708 // -- ecx : key
2702 // -- edx : receiver 2709 // -- edx : receiver
2703 // -- esp[0] : return address 2710 // -- esp[0] : return address
2704 // ----------------------------------- 2711 // -----------------------------------
2705 Label miss; 2712 Label miss, miss_force_generic;
2706 2713
2707 // Check that the receiver isn't a smi. 2714 __ CheckMap(edx, receiver_map, &miss, false);
2708 __ test(edx, Immediate(kSmiTagMask));
2709 __ j(zero, &miss, not_taken);
2710
2711 // Check that the map matches.
2712 __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
2713 Immediate(Handle<Map>(receiver->map())));
2714 __ j(not_equal, &miss, not_taken);
2715 2715
2716 // Check that the key is a smi. 2716 // Check that the key is a smi.
2717 __ test(ecx, Immediate(kSmiTagMask)); 2717 __ test(ecx, Immediate(kSmiTagMask));
2718 __ j(not_zero, &miss, not_taken); 2718 __ j(not_zero, &miss_force_generic, not_taken);
2719 2719
2720 // Get the elements array and make sure it is a fast element array, not 'cow'. 2720 // Get the elements array and make sure it is a fast element array, not 'cow'.
2721 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); 2721 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
2722 __ cmp(FieldOperand(edi, HeapObject::kMapOffset), 2722 __ cmp(FieldOperand(edi, HeapObject::kMapOffset),
2723 Immediate(factory()->fixed_array_map())); 2723 Immediate(factory()->fixed_array_map()));
2724 __ j(not_equal, &miss, not_taken); 2724 __ j(not_equal, &miss_force_generic, not_taken);
2725 2725
2726 // Check that the key is within bounds. 2726 // Check that the key is within bounds.
2727 if (receiver->IsJSArray()) { 2727 if (receiver_map->instance_type() == JS_ARRAY_TYPE) {
2728 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // Compare smis. 2728 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // smis.
2729 __ j(above_equal, &miss, not_taken); 2729 __ j(above_equal, &miss_force_generic, not_taken);
2730 } else { 2730 } else {
2731 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); // Compare smis. 2731 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); // smis.
2732 __ j(above_equal, &miss, not_taken); 2732 __ j(above_equal, &miss_force_generic, not_taken);
2733 } 2733 }
2734 2734
2735 // Do the store and update the write barrier. Make sure to preserve 2735 // Do the store and update the write barrier. Make sure to preserve
2736 // the value in register eax. 2736 // the value in register eax.
2737 __ mov(edx, Operand(eax)); 2737 __ mov(edx, Operand(eax));
2738 __ mov(FieldOperand(edi, ecx, times_2, FixedArray::kHeaderSize), eax); 2738 __ mov(FieldOperand(edi, ecx, times_2, FixedArray::kHeaderSize), eax);
2739 __ RecordWrite(edi, 0, edx, ecx); 2739 __ RecordWrite(edi, 0, edx, ecx);
2740 2740
2741 // Done. 2741 // Done.
2742 __ ret(0); 2742 __ ret(0);
2743 2743
2744 // Handle store cache miss. 2744 // Handle store cache miss.
2745 __ bind(&miss); 2745 __ bind(&miss);
2746 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); 2746 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
2747 __ jmp(ic, RelocInfo::CODE_TARGET); 2747 __ jmp(ic, RelocInfo::CODE_TARGET);
2748 2748
2749 // Handle store cache miss, replacing the ic with the generic stub.
2750 __ bind(&miss_force_generic);
2751 Handle<Code> ic_force_generic =
2752 isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
2753 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET);
2754
2749 // Return the generated code. 2755 // Return the generated code.
2750 return GetCode(NORMAL, NULL); 2756 return GetCode(NORMAL, NULL);
2751 } 2757 }
2752 2758
2753 2759
2760 MaybeObject* KeyedStoreStubCompiler::CompileStoreMegamorphic(
2761 ZoneMapList* receiver_maps,
2762 ZoneCodeList* handler_ics) {
2763 // ----------- S t a t e -------------
2764 // -- eax : receiver
2765 // -- ecx : name
2766 // -- esp[0] : return address
2767 // -----------------------------------
2768 Label miss;
2769 __ JumpIfSmi(eax, &miss);
2770
2771 int receiver_count = receiver_maps->length();
2772 for (int current = 0; current < receiver_count; ++current) {
2773 // Check map and tail call if there's a match
2774 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), receiver_maps->at(current) );
2775 __ j(equal, handler_ics->at(current));
2776 }
2777 __ bind(&miss);
2778 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
2779 __ jmp(ic, RelocInfo::CODE_TARGET);
2780
2781 // Return the generated code.
2782 return GetCode(NORMAL, NULL, MEGAMORPHIC);
2783 }
2784
2785
2754 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, 2786 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name,
2755 JSObject* object, 2787 JSObject* object,
2756 JSObject* last) { 2788 JSObject* last) {
2757 // ----------- S t a t e ------------- 2789 // ----------- S t a t e -------------
2758 // -- eax : receiver 2790 // -- eax : receiver
2759 // -- ecx : name 2791 // -- ecx : name
2760 // -- esp[0] : return address 2792 // -- esp[0] : return address
2761 // ----------------------------------- 2793 // -----------------------------------
2762 Label miss; 2794 Label miss;
2763 2795
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
3153 GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss); 3185 GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss);
3154 __ bind(&miss); 3186 __ bind(&miss);
3155 __ DecrementCounter(counters->keyed_load_function_prototype(), 1); 3187 __ DecrementCounter(counters->keyed_load_function_prototype(), 1);
3156 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3188 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3157 3189
3158 // Return the generated code. 3190 // Return the generated code.
3159 return GetCode(CALLBACKS, name); 3191 return GetCode(CALLBACKS, name);
3160 } 3192 }
3161 3193
3162 3194
3163 MaybeObject* KeyedLoadStubCompiler::CompileLoadSpecialized(JSObject* receiver) { 3195 MaybeObject* KeyedLoadStubCompiler::CompileLoadSpecialized(
3196 Handle<Map> receiver_map) {
3164 // ----------- S t a t e ------------- 3197 // ----------- S t a t e -------------
3165 // -- eax : key 3198 // -- eax : key
3166 // -- edx : receiver 3199 // -- edx : receiver
3167 // -- esp[0] : return address 3200 // -- esp[0] : return address
3168 // ----------------------------------- 3201 // -----------------------------------
3169 Label miss; 3202 Label miss, miss_force_generic;
3170 3203
3171 // Check that the receiver isn't a smi. 3204 __ CheckMap(edx, receiver_map, &miss, false);
3172 __ test(edx, Immediate(kSmiTagMask));
3173 __ j(zero, &miss, not_taken);
3174
3175 // Check that the map matches.
3176 __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
3177 Immediate(Handle<Map>(receiver->map())));
3178 __ j(not_equal, &miss, not_taken);
3179 3205
3180 // Check that the key is a smi. 3206 // Check that the key is a smi.
3181 __ test(eax, Immediate(kSmiTagMask)); 3207 __ test(eax, Immediate(kSmiTagMask));
3182 __ j(not_zero, &miss, not_taken); 3208 __ j(not_zero, &miss_force_generic, not_taken);
3183 3209
3184 // Get the elements array. 3210 // Get the elements array.
3185 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); 3211 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset));
3186 __ AssertFastElements(ecx); 3212 __ AssertFastElements(ecx);
3187 3213
3188 // Check that the key is within bounds. 3214 // Check that the key is within bounds.
3189 __ cmp(eax, FieldOperand(ecx, FixedArray::kLengthOffset)); 3215 __ cmp(eax, FieldOperand(ecx, FixedArray::kLengthOffset));
3190 __ j(above_equal, &miss, not_taken); 3216 __ j(above_equal, &miss_force_generic, not_taken);
3191 3217
3192 // Load the result and make sure it's not the hole. 3218 // Load the result and make sure it's not the hole.
3193 __ mov(ebx, Operand(ecx, eax, times_2, 3219 __ mov(ebx, Operand(ecx, eax, times_2,
3194 FixedArray::kHeaderSize - kHeapObjectTag)); 3220 FixedArray::kHeaderSize - kHeapObjectTag));
3195 __ cmp(ebx, factory()->the_hole_value()); 3221 __ cmp(ebx, factory()->the_hole_value());
3196 __ j(equal, &miss, not_taken); 3222 __ j(equal, &miss_force_generic, not_taken);
3197 __ mov(eax, ebx); 3223 __ mov(eax, ebx);
3198 __ ret(0); 3224 __ ret(0);
3199 3225
3200 __ bind(&miss); 3226 __ bind(&miss);
3201 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3227 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3202 3228
3229 __ bind(&miss_force_generic);
3230 GenerateKeyedLoadMissForceGeneric(masm());
3231
3203 // Return the generated code. 3232 // Return the generated code.
3204 return GetCode(NORMAL, NULL); 3233 return GetCode(NORMAL, NULL);
3205 } 3234 }
3206 3235
3207 3236
3237 MaybeObject* KeyedLoadStubCompiler::CompileLoadMegamorphic(
3238 ZoneMapList* receiver_maps,
3239 ZoneCodeList* handler_ics) {
3240 // ----------- S t a t e -------------
3241 // -- eax : key
3242 // -- edx : receiver
3243 // -- esp[0] : return address
3244 // -----------------------------------
3245 Label miss;
3246
3247 __ JumpIfSmi(eax, &miss);
3248
3249 int receiver_count = receiver_maps->length();
3250 for (int current = 0; current < receiver_count; ++current) {
3251 // Check map and tail call if there's a match
3252 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), receiver_maps->at(current) );
3253 __ j(equal, handler_ics->at(current));
3254 }
3255 __bind(&miss);
3256 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3257
3258 // Return the generated code.
3259 return GetCode(NORMAL, NULL, MEGAMORPHIC);
3260 }
3261
3262
3208 // Specialized stub for constructing objects from functions which only have only 3263 // Specialized stub for constructing objects from functions which only have only
3209 // simple assignments of the form this.x = ...; in their body. 3264 // simple assignments of the form this.x = ...; in their body.
3210 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { 3265 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) {
3211 // ----------- S t a t e ------------- 3266 // ----------- S t a t e -------------
3212 // -- eax : argc 3267 // -- eax : argc
3213 // -- edi : constructor 3268 // -- edi : constructor
3214 // -- esp[0] : return address 3269 // -- esp[0] : return address
3215 // -- esp[4] : last argument 3270 // -- esp[4] : last argument
3216 // ----------------------------------- 3271 // -----------------------------------
3217 Label generic_stub_call; 3272 Label generic_stub_call;
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
3344 } 3399 }
3345 3400
3346 3401
3347 MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub( 3402 MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub(
3348 JSObject*receiver, ExternalArrayType array_type, Code::Flags flags) { 3403 JSObject*receiver, ExternalArrayType array_type, Code::Flags flags) {
3349 // ----------- S t a t e ------------- 3404 // ----------- S t a t e -------------
3350 // -- eax : key 3405 // -- eax : key
3351 // -- edx : receiver 3406 // -- edx : receiver
3352 // -- esp[0] : return address 3407 // -- esp[0] : return address
3353 // ----------------------------------- 3408 // -----------------------------------
3354 Label slow, failed_allocation; 3409 Label slow, failed_allocation, miss;
3355 3410
3356 // Check that the object isn't a smi. 3411 // Check that the object isn't a smi.
3357 __ test(edx, Immediate(kSmiTagMask)); 3412 __ test(edx, Immediate(kSmiTagMask));
3358 __ j(zero, &slow, not_taken); 3413 __ j(zero, &miss, not_taken);
3359 3414
3360 // Check that the key is a smi. 3415 // Check that the key is a smi.
3361 __ test(eax, Immediate(kSmiTagMask)); 3416 __ test(eax, Immediate(kSmiTagMask));
3362 __ j(not_zero, &slow, not_taken); 3417 __ j(not_zero, &miss, not_taken);
3363 3418
3364 // Check that the map matches. 3419 // Check that the map matches.
3365 __ CheckMap(edx, Handle<Map>(receiver->map()), &slow, false); 3420 __ CheckMap(edx, Handle<Map>(receiver->map()), &miss, false);
3366 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset)); 3421 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
3367 3422
3368 // eax: key, known to be a smi. 3423 // eax: key, known to be a smi.
3369 // edx: receiver, known to be a JSObject. 3424 // edx: receiver, known to be a JSObject.
3370 // ebx: elements object, known to be an external array. 3425 // ebx: elements object, known to be an external array.
3371 // Check that the index is in range. 3426 // Check that the index is in range.
3372 __ mov(ecx, eax); 3427 __ mov(ecx, eax);
3373 __ SmiUntag(ecx); // Untag the index. 3428 __ SmiUntag(ecx); // Untag the index.
3374 __ cmp(ecx, FieldOperand(ebx, ExternalArray::kLengthOffset)); 3429 __ cmp(ecx, FieldOperand(ebx, ExternalArray::kLengthOffset));
3375 // Unsigned comparison catches both negative and too-large values. 3430 // Unsigned comparison catches both negative and too-large values.
3376 __ j(above_equal, &slow); 3431 __ j(above_equal, &miss);
3377 __ mov(ebx, FieldOperand(ebx, ExternalArray::kExternalPointerOffset)); 3432 __ mov(ebx, FieldOperand(ebx, ExternalArray::kExternalPointerOffset));
3378 // ebx: base pointer of external storage 3433 // ebx: base pointer of external storage
3379 switch (array_type) { 3434 switch (array_type) {
3380 case kExternalByteArray: 3435 case kExternalByteArray:
3381 __ movsx_b(eax, Operand(ebx, ecx, times_1, 0)); 3436 __ movsx_b(eax, Operand(ebx, ecx, times_1, 0));
3382 break; 3437 break;
3383 case kExternalUnsignedByteArray: 3438 case kExternalUnsignedByteArray:
3384 case kExternalPixelArray: 3439 case kExternalPixelArray:
3385 __ movzx_b(eax, Operand(ebx, ecx, times_1, 0)); 3440 __ movzx_b(eax, Operand(ebx, ecx, times_1, 0));
3386 break; 3441 break;
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
3475 // top of the FPU stack. Remove it. 3530 // top of the FPU stack. Remove it.
3476 __ bind(&failed_allocation); 3531 __ bind(&failed_allocation);
3477 __ ffree(); 3532 __ ffree();
3478 __ fincstp(); 3533 __ fincstp();
3479 // Fall through to slow case. 3534 // Fall through to slow case.
3480 3535
3481 // Slow case: Jump to runtime. 3536 // Slow case: Jump to runtime.
3482 __ bind(&slow); 3537 __ bind(&slow);
3483 Counters* counters = isolate()->counters(); 3538 Counters* counters = isolate()->counters();
3484 __ IncrementCounter(counters->keyed_load_external_array_slow(), 1); 3539 __ IncrementCounter(counters->keyed_load_external_array_slow(), 1);
3540
3485 // ----------- S t a t e ------------- 3541 // ----------- S t a t e -------------
3486 // -- eax : key 3542 // -- eax : key
3487 // -- edx : receiver 3543 // -- edx : receiver
3488 // -- esp[0] : return address 3544 // -- esp[0] : return address
3489 // ----------------------------------- 3545 // -----------------------------------
3490 3546
3491 __ pop(ebx); 3547 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Slow();
3492 __ push(edx); // receiver 3548 __ jmp(ic, RelocInfo::CODE_TARGET);
3493 __ push(eax); // name
3494 __ push(ebx); // return address
3495 3549
3496 // Perform tail call to the entry. 3550 __ bind(&miss);
3497 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); 3551 // ----------- S t a t e -------------
3552 // -- eax : key
3553 // -- edx : receiver
3554 // -- esp[0] : return address
3555 // -----------------------------------
3556
3557 Handle<Code> miss_ic = isolate()->builtins()->KeyedLoadIC_Miss();
3558 __ jmp(miss_ic, RelocInfo::CODE_TARGET);
3498 3559
3499 // Return the generated code. 3560 // Return the generated code.
3500 return GetCode(flags); 3561 return GetCode(flags);
3501 } 3562 }
3502 3563
3503 3564
3504 MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub( 3565 MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub(
3505 JSObject* receiver, ExternalArrayType array_type, Code::Flags flags) { 3566 JSObject* receiver, ExternalArrayType array_type, Code::Flags flags) {
3506 // ----------- S t a t e ------------- 3567 // ----------- S t a t e -------------
3507 // -- eax : value 3568 // -- eax : value
3508 // -- ecx : key 3569 // -- ecx : key
3509 // -- edx : receiver 3570 // -- edx : receiver
3510 // -- esp[0] : return address 3571 // -- esp[0] : return address
3511 // ----------------------------------- 3572 // -----------------------------------
3512 Label slow, check_heap_number; 3573 Label slow, check_heap_number, miss;
3513 3574
3514 // Check that the object isn't a smi. 3575 // Check that the object isn't a smi.
3515 __ test(edx, Immediate(kSmiTagMask)); 3576 __ test(edx, Immediate(kSmiTagMask));
3516 __ j(zero, &slow); 3577 __ j(zero, &miss);
3517 3578
3518 // Check that the map matches. 3579 // Check that the map matches.
3519 __ CheckMap(edx, Handle<Map>(receiver->map()), &slow, false); 3580 __ CheckMap(edx, Handle<Map>(receiver->map()), &miss, false);
3520 3581
3521 // Check that the key is a smi. 3582 // Check that the key is a smi.
3522 __ test(ecx, Immediate(kSmiTagMask)); 3583 __ test(ecx, Immediate(kSmiTagMask));
3523 __ j(not_zero, &slow); 3584 __ j(not_zero, &miss);
3524 3585
3525 // Check that the index is in range. 3586 // Check that the index is in range.
3526 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); 3587 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
3527 __ mov(ebx, ecx); 3588 __ mov(ebx, ecx);
3528 __ SmiUntag(ebx); 3589 __ SmiUntag(ebx);
3529 __ cmp(ebx, FieldOperand(edi, ExternalArray::kLengthOffset)); 3590 __ cmp(ebx, FieldOperand(edi, ExternalArray::kLengthOffset));
3530 // Unsigned comparison catches both negative and too-large values. 3591 // Unsigned comparison catches both negative and too-large values.
3531 __ j(above_equal, &slow); 3592 __ j(above_equal, &slow);
3532 3593
3533 // Handle both smis and HeapNumbers in the fast path. Go to the 3594 // Handle both smis and HeapNumbers in the fast path. Go to the
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
3687 // ecx: untagged integer value 3748 // ecx: untagged integer value
3688 __ mov(Operand(edi, ebx, times_4, 0), ecx); 3749 __ mov(Operand(edi, ebx, times_4, 0), ecx);
3689 } 3750 }
3690 __ ret(0); // Return original value. 3751 __ ret(0); // Return original value.
3691 } 3752 }
3692 } 3753 }
3693 } 3754 }
3694 3755
3695 // Slow case: call runtime. 3756 // Slow case: call runtime.
3696 __ bind(&slow); 3757 __ bind(&slow);
3758 Counters* counters = isolate()->counters();
3759 __ IncrementCounter(counters->keyed_store_external_array_slow(), 1);
3760
3697 // ----------- S t a t e ------------- 3761 // ----------- S t a t e -------------
3698 // -- eax : value 3762 // -- eax : value
3699 // -- ecx : key 3763 // -- ecx : key
3700 // -- edx : receiver 3764 // -- edx : receiver
3701 // -- esp[0] : return address 3765 // -- esp[0] : return address
3702 // ----------------------------------- 3766 // -----------------------------------
3703 3767
3704 __ pop(ebx); 3768 bool strict = (Code::ExtractExtraICStateFromFlags(flags) & kStrictMode) != 0;
3705 __ push(edx); 3769 Handle<Code> ic = strict
3706 __ push(ecx); 3770 ? isolate()->builtins()->KeyedStoreIC_Slow_Strict()
3707 __ push(eax); 3771 : isolate()->builtins()->KeyedStoreIC_Slow_NonStrict();
3708 __ push(Immediate(Smi::FromInt(NONE))); // PropertyAttributes 3772 __ jmp(ic, RelocInfo::CODE_TARGET);
3709 __ push(Immediate(Smi::FromInt(
3710 Code::ExtractExtraICStateFromFlags(flags) & kStrictMode)));
3711 __ push(ebx); // return address
3712 3773
3713 // Do tail-call to runtime routine. 3774 // Miss case: call runtime.
3714 __ TailCallRuntime(Runtime::kSetProperty, 5, 1); 3775 __ bind(&miss);
3776 // ----------- S t a t e -------------
3777 // -- eax : value
3778 // -- ecx : key
3779 // -- edx : receiver
3780 // -- esp[0] : return address
3781 // -----------------------------------
3782
3783 Handle<Code> miss_ic = isolate()->builtins()->KeyedStoreIC_Miss();
3784 __ jmp(miss_ic, RelocInfo::CODE_TARGET);
3715 3785
3716 return GetCode(flags); 3786 return GetCode(flags);
3717 } 3787 }
3718 3788
3719 3789
3720 #undef __ 3790 #undef __
3721 3791
3722 } } // namespace v8::internal 3792 } } // namespace v8::internal
3723 3793
3724 #endif // V8_TARGET_ARCH_IA32 3794 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/macro-assembler-ia32.cc ('k') | src/ic.h » ('j') | src/ic.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698