| 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 |