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

Side by Side Diff: src/x64/stub-cache-x64.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, 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 729 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
OLDNEW
« src/ic.cc ('K') | « src/x64/macro-assembler-x64.cc ('k') | src/zone.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698