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

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: review feedback and merge Created 9 years, 7 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 695 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 code = masm->isolate()->builtins()->builtin(Builtins::kLoadIC_Miss); 706 code = masm->isolate()->builtins()->builtin(Builtins::kLoadIC_Miss);
707 } else { 707 } else {
708 code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss); 708 code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss);
709 } 709 }
710 710
711 Handle<Code> ic(code); 711 Handle<Code> ic(code);
712 __ jmp(ic, RelocInfo::CODE_TARGET); 712 __ jmp(ic, RelocInfo::CODE_TARGET);
713 } 713 }
714 714
715 715
716 void StubCompiler::GenerateKeyedLoadMissForceGeneric(MacroAssembler* masm) {
717 Code* code = masm->isolate()->builtins()->builtin(
718 Builtins::kKeyedLoadIC_MissForceGeneric);
719 Handle<Code> ic(code);
720 __ jmp(ic, RelocInfo::CODE_TARGET);
721 }
722
723
716 // Both name_reg and receiver_reg are preserved on jumps to miss_label, 724 // Both name_reg and receiver_reg are preserved on jumps to miss_label,
717 // but may be destroyed if store is successful. 725 // but may be destroyed if store is successful.
718 void StubCompiler::GenerateStoreField(MacroAssembler* masm, 726 void StubCompiler::GenerateStoreField(MacroAssembler* masm,
719 JSObject* object, 727 JSObject* object,
720 int index, 728 int index,
721 Map* transition, 729 Map* transition,
722 Register receiver_reg, 730 Register receiver_reg,
723 Register name_reg, 731 Register name_reg,
724 Register scratch, 732 Register scratch,
725 Label* miss_label) { 733 Label* miss_label) {
(...skipping 1921 matching lines...) Expand 10 before | Expand all | Expand 10 after
2647 __ bind(&miss); 2655 __ bind(&miss);
2648 __ DecrementCounter(counters->keyed_store_field(), 1); 2656 __ DecrementCounter(counters->keyed_store_field(), 1);
2649 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); 2657 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
2650 __ jmp(ic, RelocInfo::CODE_TARGET); 2658 __ jmp(ic, RelocInfo::CODE_TARGET);
2651 2659
2652 // Return the generated code. 2660 // Return the generated code.
2653 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); 2661 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name);
2654 } 2662 }
2655 2663
2656 2664
2657 MaybeObject* KeyedStoreStubCompiler::CompileStoreSpecialized( 2665 MaybeObject* KeyedStoreStubCompiler::CompileStoreFastElement(
2658 JSObject* receiver) { 2666 Map* receiver_map) {
2659 // ----------- S t a t e ------------- 2667 // ----------- S t a t e -------------
2660 // -- eax : value 2668 // -- eax : value
2661 // -- ecx : key 2669 // -- ecx : key
2662 // -- edx : receiver 2670 // -- edx : receiver
2663 // -- esp[0] : return address 2671 // -- esp[0] : return address
2664 // ----------------------------------- 2672 // -----------------------------------
2665 Label miss; 2673 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
2674 MaybeObject* maybe_stub =
2675 KeyedStoreFastElementStub(is_js_array).TryGetCode();
2676 Code* stub;
2677 if (!maybe_stub->To(&stub)) return maybe_stub;
2678 __ DispatchMap(edx,
2679 Handle<Map>(receiver_map),
2680 Handle<Code>(stub),
2681 false);
2666 2682
2667 // Check that the receiver isn't a smi.
2668 __ test(edx, Immediate(kSmiTagMask));
2669 __ j(zero, &miss);
2670
2671 // Check that the map matches.
2672 __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
2673 Immediate(Handle<Map>(receiver->map())));
2674 __ j(not_equal, &miss);
2675
2676 // Check that the key is a smi.
2677 __ test(ecx, Immediate(kSmiTagMask));
2678 __ j(not_zero, &miss);
2679
2680 // Get the elements array and make sure it is a fast element array, not 'cow'.
2681 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
2682 __ cmp(FieldOperand(edi, HeapObject::kMapOffset),
2683 Immediate(factory()->fixed_array_map()));
2684 __ j(not_equal, &miss);
2685
2686 // Check that the key is within bounds.
2687 if (receiver->IsJSArray()) {
2688 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // Compare smis.
2689 __ j(above_equal, &miss);
2690 } else {
2691 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); // Compare smis.
2692 __ j(above_equal, &miss);
2693 }
2694
2695 // Do the store and update the write barrier. Make sure to preserve
2696 // the value in register eax.
2697 __ mov(edx, Operand(eax));
2698 __ mov(FieldOperand(edi, ecx, times_2, FixedArray::kHeaderSize), eax);
2699 __ RecordWrite(edi, 0, edx, ecx);
2700
2701 // Done.
2702 __ ret(0);
2703
2704 // Handle store cache miss.
2705 __ bind(&miss);
2706 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); 2683 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
2707 __ jmp(ic, RelocInfo::CODE_TARGET); 2684 __ jmp(ic, RelocInfo::CODE_TARGET);
2708 2685
2709 // Return the generated code. 2686 // Return the generated code.
2710 return GetCode(NORMAL, NULL); 2687 return GetCode(NORMAL, NULL);
2711 } 2688 }
2712 2689
2713 2690
2691 MaybeObject* KeyedStoreStubCompiler::CompileStoreMegamorphic(
2692 MapList* receiver_maps,
2693 CodeList* handler_ics) {
2694 // ----------- S t a t e -------------
2695 // -- eax : value
2696 // -- ecx : key
2697 // -- edx : receiver
2698 // -- esp[0] : return address
2699 // -----------------------------------
2700 Label miss;
2701 __ JumpIfSmi(edx, &miss);
2702
2703 int receiver_count = receiver_maps->length();
2704 for (int current = 0; current < receiver_count; ++current) {
2705 Handle<Map> map(receiver_maps->at(current));
2706 __ DispatchMap(edx, map, Handle<Code>(handler_ics->at(current)), true);
2707 }
2708 __ bind(&miss);
2709 Handle<Code> miss_ic = isolate()->builtins()->KeyedStoreIC_Miss();
2710 __ jmp(miss_ic, RelocInfo::CODE_TARGET);
2711
2712 // Return the generated code.
2713 return GetCode(NORMAL, NULL, MEGAMORPHIC);
2714 }
2715
2716
2714 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, 2717 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name,
2715 JSObject* object, 2718 JSObject* object,
2716 JSObject* last) { 2719 JSObject* last) {
2717 // ----------- S t a t e ------------- 2720 // ----------- S t a t e -------------
2718 // -- eax : receiver 2721 // -- eax : receiver
2719 // -- ecx : name 2722 // -- ecx : name
2720 // -- esp[0] : return address 2723 // -- esp[0] : return address
2721 // ----------------------------------- 2724 // -----------------------------------
2722 Label miss; 2725 Label miss;
2723 2726
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
3113 GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss); 3116 GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss);
3114 __ bind(&miss); 3117 __ bind(&miss);
3115 __ DecrementCounter(counters->keyed_load_function_prototype(), 1); 3118 __ DecrementCounter(counters->keyed_load_function_prototype(), 1);
3116 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3119 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3117 3120
3118 // Return the generated code. 3121 // Return the generated code.
3119 return GetCode(CALLBACKS, name); 3122 return GetCode(CALLBACKS, name);
3120 } 3123 }
3121 3124
3122 3125
3123 MaybeObject* KeyedLoadStubCompiler::CompileLoadSpecialized(JSObject* receiver) { 3126 MaybeObject* KeyedLoadStubCompiler::CompileLoadFastElement(Map* receiver_map) {
3124 // ----------- S t a t e ------------- 3127 // ----------- S t a t e -------------
3125 // -- eax : key 3128 // -- eax : key
3126 // -- edx : receiver 3129 // -- edx : receiver
3127 // -- esp[0] : return address 3130 // -- esp[0] : return address
3128 // ----------------------------------- 3131 // -----------------------------------
3129 Label miss; 3132 MaybeObject* maybe_stub = KeyedLoadFastElementStub().TryGetCode();
3133 Code* stub;
3134 if (!maybe_stub->To(&stub)) return maybe_stub;
3135 __ DispatchMap(edx,
3136 Handle<Map>(receiver_map),
3137 Handle<Code>(stub),
3138 false);
3130 3139
3131 // Check that the receiver isn't a smi.
3132 __ test(edx, Immediate(kSmiTagMask));
3133 __ j(zero, &miss);
3134
3135 // Check that the map matches.
3136 __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
3137 Immediate(Handle<Map>(receiver->map())));
3138 __ j(not_equal, &miss);
3139
3140 // Check that the key is a smi.
3141 __ test(eax, Immediate(kSmiTagMask));
3142 __ j(not_zero, &miss);
3143
3144 // Get the elements array.
3145 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset));
3146 __ AssertFastElements(ecx);
3147
3148 // Check that the key is within bounds.
3149 __ cmp(eax, FieldOperand(ecx, FixedArray::kLengthOffset));
3150 __ j(above_equal, &miss);
3151
3152 // Load the result and make sure it's not the hole.
3153 __ mov(ebx, Operand(ecx, eax, times_2,
3154 FixedArray::kHeaderSize - kHeapObjectTag));
3155 __ cmp(ebx, factory()->the_hole_value());
3156 __ j(equal, &miss);
3157 __ mov(eax, ebx);
3158 __ ret(0);
3159
3160 __ bind(&miss);
3161 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3140 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3162 3141
3163 // Return the generated code. 3142 // Return the generated code.
3164 return GetCode(NORMAL, NULL); 3143 return GetCode(NORMAL, NULL);
3165 } 3144 }
3166 3145
3167 3146
3147 MaybeObject* KeyedLoadStubCompiler::CompileLoadMegamorphic(
3148 MapList* receiver_maps,
3149 CodeList* handler_ics) {
3150 // ----------- S t a t e -------------
3151 // -- eax : key
3152 // -- edx : receiver
3153 // -- esp[0] : return address
3154 // -----------------------------------
3155 Label miss;
3156 __ JumpIfSmi(edx, &miss);
3157
3158 int receiver_count = receiver_maps->length();
3159 for (int current = 0; current < receiver_count; ++current) {
3160 Handle<Map> map(receiver_maps->at(current));
3161 __ DispatchMap(edx, map, Handle<Code>(handler_ics->at(current)), true);
3162 }
3163 __ bind(&miss);
3164 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3165
3166 // Return the generated code.
3167 return GetCode(NORMAL, NULL, MEGAMORPHIC);
3168 }
3169
3170
3168 // Specialized stub for constructing objects from functions which only have only 3171 // Specialized stub for constructing objects from functions which only have only
3169 // simple assignments of the form this.x = ...; in their body. 3172 // simple assignments of the form this.x = ...; in their body.
3170 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { 3173 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) {
3171 // ----------- S t a t e ------------- 3174 // ----------- S t a t e -------------
3172 // -- eax : argc 3175 // -- eax : argc
3173 // -- edi : constructor 3176 // -- edi : constructor
3174 // -- esp[0] : return address 3177 // -- esp[0] : return address
3175 // -- esp[4] : last argument 3178 // -- esp[4] : last argument
3176 // ----------------------------------- 3179 // -----------------------------------
3177 Label generic_stub_call; 3180 Label generic_stub_call;
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
3297 __ bind(&generic_stub_call); 3300 __ bind(&generic_stub_call);
3298 Handle<Code> generic_construct_stub = 3301 Handle<Code> generic_construct_stub =
3299 isolate()->builtins()->JSConstructStubGeneric(); 3302 isolate()->builtins()->JSConstructStubGeneric();
3300 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); 3303 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET);
3301 3304
3302 // Return the generated code. 3305 // Return the generated code.
3303 return GetCode(); 3306 return GetCode();
3304 } 3307 }
3305 3308
3306 3309
3307 MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub( 3310 MaybeObject* ExternalArrayLoadStubCompiler::CompileLoad(
3308 JSObject*receiver, ExternalArrayType array_type, Code::Flags flags) { 3311 JSObject*receiver, ExternalArrayType array_type) {
3309 // ----------- S t a t e ------------- 3312 // ----------- S t a t e -------------
3310 // -- eax : key 3313 // -- eax : key
3311 // -- edx : receiver 3314 // -- edx : receiver
3312 // -- esp[0] : return address 3315 // -- esp[0] : return address
3313 // ----------------------------------- 3316 // -----------------------------------
3314 Label slow, failed_allocation; 3317 MaybeObject* maybe_stub =
3318 KeyedLoadExternalArrayStub(array_type).TryGetCode();
3319 Code* stub;
3320 if (!maybe_stub->To(&stub)) return maybe_stub;
3321 __ DispatchMap(edx, Handle<Map>(receiver->map()), Handle<Code>(stub), false);
3315 3322
3316 // Check that the object isn't a smi. 3323 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss();
3317 __ test(edx, Immediate(kSmiTagMask)); 3324 __ jmp(ic, RelocInfo::CODE_TARGET);
3318 __ j(zero, &slow); 3325
3326 // Return the generated code.
3327 return GetCode();
3328 }
3329
3330
3331 MaybeObject* ExternalArrayStoreStubCompiler::CompileStore(
3332 JSObject* receiver, ExternalArrayType array_type) {
3333 // ----------- S t a t e -------------
3334 // -- eax : value
3335 // -- ecx : key
3336 // -- edx : receiver
3337 // -- esp[0] : return address
3338 // -----------------------------------
3339 MaybeObject* maybe_stub =
3340 KeyedStoreExternalArrayStub(array_type).TryGetCode();
3341 Code* stub;
3342 if (!maybe_stub->To(&stub)) return maybe_stub;
3343 __ DispatchMap(edx, Handle<Map>(receiver->map()), Handle<Code>(stub), false);
3344
3345 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
3346 __ jmp(ic, RelocInfo::CODE_TARGET);
3347
3348 return GetCode();
3349 }
3350
3351
3352 #undef __
3353 #define __ ACCESS_MASM(masm)
3354
3355
3356 void KeyedLoadStubCompiler::GenerateLoadExternalArray(
3357 MacroAssembler* masm,
3358 ExternalArrayType array_type) {
3359 // ----------- S t a t e -------------
3360 // -- eax : key
3361 // -- edx : receiver
3362 // -- esp[0] : return address
3363 // -----------------------------------
3364 Label miss_force_generic, failed_allocation, slow;
3365
3366 // This stub is meant to be tail-jumped to, the receiver must already
3367 // have been verified by the caller to not be a smi.
3319 3368
3320 // Check that the key is a smi. 3369 // Check that the key is a smi.
3321 __ test(eax, Immediate(kSmiTagMask)); 3370 __ test(eax, Immediate(kSmiTagMask));
3322 __ j(not_zero, &slow); 3371 __ j(not_zero, &miss_force_generic);
3323 3372
3324 // Check that the map matches.
3325 __ CheckMap(edx, Handle<Map>(receiver->map()), &slow, false);
3326 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
3327
3328 // eax: key, known to be a smi.
3329 // edx: receiver, known to be a JSObject.
3330 // ebx: elements object, known to be an external array.
3331 // Check that the index is in range. 3373 // Check that the index is in range.
3332 __ mov(ecx, eax); 3374 __ mov(ecx, eax);
3333 __ SmiUntag(ecx); // Untag the index. 3375 __ SmiUntag(ecx); // Untag the index.
3376 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
3334 __ cmp(ecx, FieldOperand(ebx, ExternalArray::kLengthOffset)); 3377 __ cmp(ecx, FieldOperand(ebx, ExternalArray::kLengthOffset));
3335 // Unsigned comparison catches both negative and too-large values. 3378 // Unsigned comparison catches both negative and too-large values.
3336 __ j(above_equal, &slow); 3379 __ j(above_equal, &miss_force_generic);
3337 __ mov(ebx, FieldOperand(ebx, ExternalArray::kExternalPointerOffset)); 3380 __ mov(ebx, FieldOperand(ebx, ExternalArray::kExternalPointerOffset));
3338 // ebx: base pointer of external storage 3381 // ebx: base pointer of external storage
3339 switch (array_type) { 3382 switch (array_type) {
3340 case kExternalByteArray: 3383 case kExternalByteArray:
3341 __ movsx_b(eax, Operand(ebx, ecx, times_1, 0)); 3384 __ movsx_b(eax, Operand(ebx, ecx, times_1, 0));
3342 break; 3385 break;
3343 case kExternalUnsignedByteArray: 3386 case kExternalUnsignedByteArray:
3344 case kExternalPixelArray: 3387 case kExternalPixelArray:
3345 __ movzx_b(eax, Operand(ebx, ecx, times_1, 0)); 3388 __ movzx_b(eax, Operand(ebx, ecx, times_1, 0));
3346 break; 3389 break;
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
3433 3476
3434 // If we fail allocation of the HeapNumber, we still have a value on 3477 // If we fail allocation of the HeapNumber, we still have a value on
3435 // top of the FPU stack. Remove it. 3478 // top of the FPU stack. Remove it.
3436 __ bind(&failed_allocation); 3479 __ bind(&failed_allocation);
3437 __ ffree(); 3480 __ ffree();
3438 __ fincstp(); 3481 __ fincstp();
3439 // Fall through to slow case. 3482 // Fall through to slow case.
3440 3483
3441 // Slow case: Jump to runtime. 3484 // Slow case: Jump to runtime.
3442 __ bind(&slow); 3485 __ bind(&slow);
3443 Counters* counters = isolate()->counters(); 3486 Counters* counters = masm->isolate()->counters();
3444 __ IncrementCounter(counters->keyed_load_external_array_slow(), 1); 3487 __ IncrementCounter(counters->keyed_load_external_array_slow(), 1);
3488
3445 // ----------- S t a t e ------------- 3489 // ----------- S t a t e -------------
3446 // -- eax : key 3490 // -- eax : key
3447 // -- edx : receiver 3491 // -- edx : receiver
3448 // -- esp[0] : return address 3492 // -- esp[0] : return address
3449 // ----------------------------------- 3493 // -----------------------------------
3450 3494
3451 __ pop(ebx); 3495 Handle<Code> ic = masm->isolate()->builtins()->KeyedLoadIC_Slow();
3452 __ push(edx); // receiver 3496 __ jmp(ic, RelocInfo::CODE_TARGET);
3453 __ push(eax); // name
3454 __ push(ebx); // return address
3455 3497
3456 // Perform tail call to the entry. 3498 // ----------- S t a t e -------------
3457 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); 3499 // -- eax : key
3500 // -- edx : receiver
3501 // -- esp[0] : return address
3502 // -----------------------------------
3458 3503
3459 // Return the generated code. 3504 // Miss case: Jump to runtime.
3460 return GetCode(flags); 3505 __ bind(&miss_force_generic);
3506 Handle<Code> miss_ic =
3507 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
3508 __ jmp(miss_ic, RelocInfo::CODE_TARGET);
3461 } 3509 }
3462 3510
3463 3511
3464 MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub( 3512 void KeyedStoreStubCompiler::GenerateStoreExternalArray(
3465 JSObject* receiver, ExternalArrayType array_type, Code::Flags flags) { 3513 MacroAssembler* masm,
3514 ExternalArrayType array_type) {
3466 // ----------- S t a t e ------------- 3515 // ----------- S t a t e -------------
3467 // -- eax : value 3516 // -- eax : key
3468 // -- ecx : key
3469 // -- edx : receiver 3517 // -- edx : receiver
3470 // -- esp[0] : return address 3518 // -- esp[0] : return address
3471 // ----------------------------------- 3519 // -----------------------------------
3472 Label slow, check_heap_number; 3520 Label miss_force_generic, slow, check_heap_number;
3473 3521
3474 // Check that the object isn't a smi. 3522 // This stub is meant to be tail-jumped to, the receiver must already
3475 __ test(edx, Immediate(kSmiTagMask)); 3523 // have been verified by the caller to not be a smi.
3476 __ j(zero, &slow);
3477
3478 // Check that the map matches.
3479 __ CheckMap(edx, Handle<Map>(receiver->map()), &slow, false);
3480 3524
3481 // Check that the key is a smi. 3525 // Check that the key is a smi.
3482 __ test(ecx, Immediate(kSmiTagMask)); 3526 __ test(ecx, Immediate(kSmiTagMask));
3483 __ j(not_zero, &slow); 3527 __ j(not_zero, &miss_force_generic);
3484 3528
3485 // Check that the index is in range. 3529 // Check that the index is in range.
3486 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); 3530 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
3487 __ mov(ebx, ecx); 3531 __ mov(ebx, ecx);
3488 __ SmiUntag(ebx); 3532 __ SmiUntag(ebx);
3489 __ cmp(ebx, FieldOperand(edi, ExternalArray::kLengthOffset)); 3533 __ cmp(ebx, FieldOperand(edi, ExternalArray::kLengthOffset));
3490 // Unsigned comparison catches both negative and too-large values. 3534 // Unsigned comparison catches both negative and too-large values.
3491 __ j(above_equal, &slow); 3535 __ j(above_equal, &slow);
3492 3536
3493 // Handle both smis and HeapNumbers in the fast path. Go to the 3537 // Handle both smis and HeapNumbers in the fast path. Go to the
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
3552 3596
3553 // TODO(danno): handle heap number -> pixel array conversion 3597 // TODO(danno): handle heap number -> pixel array conversion
3554 if (array_type != kExternalPixelArray) { 3598 if (array_type != kExternalPixelArray) {
3555 __ bind(&check_heap_number); 3599 __ bind(&check_heap_number);
3556 // eax: value 3600 // eax: value
3557 // edx: receiver 3601 // edx: receiver
3558 // ecx: key 3602 // ecx: key
3559 // edi: elements array 3603 // edi: elements array
3560 // ebx: untagged index 3604 // ebx: untagged index
3561 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), 3605 __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
3562 Immediate(factory()->heap_number_map())); 3606 Immediate(masm->isolate()->factory()->heap_number_map()));
3563 __ j(not_equal, &slow); 3607 __ j(not_equal, &slow);
3564 3608
3565 // The WebGL specification leaves the behavior of storing NaN and 3609 // The WebGL specification leaves the behavior of storing NaN and
3566 // +/-Infinity into integer arrays basically undefined. For more 3610 // +/-Infinity into integer arrays basically undefined. For more
3567 // reproducible behavior, convert these to zero. 3611 // reproducible behavior, convert these to zero.
3568 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset)); 3612 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset));
3569 // ebx: untagged index 3613 // ebx: untagged index
3570 // edi: base pointer of external storage 3614 // edi: base pointer of external storage
3571 if (array_type == kExternalFloatArray) { 3615 if (array_type == kExternalFloatArray) {
3572 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); 3616 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
3647 // ecx: untagged integer value 3691 // ecx: untagged integer value
3648 __ mov(Operand(edi, ebx, times_4, 0), ecx); 3692 __ mov(Operand(edi, ebx, times_4, 0), ecx);
3649 } 3693 }
3650 __ ret(0); // Return original value. 3694 __ ret(0); // Return original value.
3651 } 3695 }
3652 } 3696 }
3653 } 3697 }
3654 3698
3655 // Slow case: call runtime. 3699 // Slow case: call runtime.
3656 __ bind(&slow); 3700 __ bind(&slow);
3701 Counters* counters = masm->isolate()->counters();
3702 __ IncrementCounter(counters->keyed_store_external_array_slow(), 1);
3703
3657 // ----------- S t a t e ------------- 3704 // ----------- S t a t e -------------
3658 // -- eax : value 3705 // -- eax : value
3659 // -- ecx : key 3706 // -- ecx : key
3660 // -- edx : receiver 3707 // -- edx : receiver
3661 // -- esp[0] : return address 3708 // -- esp[0] : return address
3662 // ----------------------------------- 3709 // -----------------------------------
3663 3710
3664 __ pop(ebx); 3711 Handle<Code> ic = masm->isolate()->builtins()->KeyedStoreIC_Slow();
3665 __ push(edx); 3712 __ jmp(ic, RelocInfo::CODE_TARGET);
3666 __ push(ecx);
3667 __ push(eax);
3668 __ push(Immediate(Smi::FromInt(NONE))); // PropertyAttributes
3669 __ push(Immediate(Smi::FromInt(
3670 Code::ExtractExtraICStateFromFlags(flags) & kStrictMode)));
3671 __ push(ebx); // return address
3672 3713
3673 // Do tail-call to runtime routine. 3714 // ----------- S t a t e -------------
3674 __ TailCallRuntime(Runtime::kSetProperty, 5, 1); 3715 // -- eax : value
3716 // -- ecx : key
3717 // -- edx : receiver
3718 // -- esp[0] : return address
3719 // -----------------------------------
3675 3720
3676 return GetCode(flags); 3721 __ bind(&miss_force_generic);
3722 Handle<Code> miss_ic =
3723 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
3724 __ jmp(miss_ic, RelocInfo::CODE_TARGET);
3677 } 3725 }
3678 3726
3679 3727
3728
3729
3730 void KeyedLoadStubCompiler::GenerateLoadFastElement(MacroAssembler* masm) {
3731 // ----------- S t a t e -------------
3732 // -- eax : key
3733 // -- edx : receiver
3734 // -- esp[0] : return address
3735 // -----------------------------------
3736 Label miss_force_generic;
3737
3738 // This stub is meant to be tail-jumped to, the receiver must already
3739 // have been verified by the caller to not be a smi.
3740
3741 // Check that the key is a smi.
3742 __ test(eax, Immediate(kSmiTagMask));
3743 __ j(not_zero, &miss_force_generic);
3744
3745 // Get the elements array.
3746 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset));
3747 __ AssertFastElements(ecx);
3748
3749 // Check that the key is within bounds.
3750 __ cmp(eax, FieldOperand(ecx, FixedArray::kLengthOffset));
3751 __ j(above_equal, &miss_force_generic);
3752
3753 // Load the result and make sure it's not the hole.
3754 __ mov(ebx, Operand(ecx, eax, times_2,
3755 FixedArray::kHeaderSize - kHeapObjectTag));
3756 __ cmp(ebx, masm->isolate()->factory()->the_hole_value());
3757 __ j(equal, &miss_force_generic);
3758 __ mov(eax, ebx);
3759 __ ret(0);
3760
3761 __ bind(&miss_force_generic);
3762 Handle<Code> miss_ic =
3763 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
3764 __ jmp(miss_ic, RelocInfo::CODE_TARGET);
3765 }
3766
3767
3768 void KeyedStoreStubCompiler::GenerateStoreFastElement(MacroAssembler* masm,
3769 bool is_js_array) {
3770 // ----------- S t a t e -------------
3771 // -- eax : key
3772 // -- edx : receiver
3773 // -- esp[0] : return address
3774 // -----------------------------------
3775 Label miss_force_generic;
3776
3777 // This stub is meant to be tail-jumped to, the receiver must already
3778 // have been verified by the caller to not be a smi.
3779
3780 // Check that the key is a smi.
3781 __ test(ecx, Immediate(kSmiTagMask));
3782 __ j(not_zero, &miss_force_generic);
3783
3784 // Get the elements array and make sure it is a fast element array, not 'cow'.
3785 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
3786 __ cmp(FieldOperand(edi, HeapObject::kMapOffset),
3787 Immediate(masm->isolate()->factory()->fixed_array_map()));
3788 __ j(not_equal, &miss_force_generic);
3789
3790 if (is_js_array) {
3791 // Check that the key is within bounds.
3792 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // smis.
3793 __ j(above_equal, &miss_force_generic);
3794 } else {
3795 // Check that the key is within bounds.
3796 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); // smis.
3797 __ j(above_equal, &miss_force_generic);
3798 }
3799
3800 // Do the store and update the write barrier. Make sure to preserve
3801 // the value in register eax.
3802 __ mov(edx, Operand(eax));
3803 __ mov(FieldOperand(edi, ecx, times_2, FixedArray::kHeaderSize), eax);
3804 __ RecordWrite(edi, 0, edx, ecx);
3805
3806 // Done.
3807 __ ret(0);
3808
3809 // Handle store cache miss, replacing the ic with the generic stub.
3810 __ bind(&miss_force_generic);
3811 Handle<Code> ic_force_generic =
3812 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
3813 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET);
3814 }
3815
3816
3680 #undef __ 3817 #undef __
3681 3818
3682 } } // namespace v8::internal 3819 } } // namespace v8::internal
3683 3820
3684 #endif // V8_TARGET_ARCH_IA32 3821 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698