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 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
419 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); | 419 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); |
420 __ mov(v0, scratch1); | 420 __ mov(v0, scratch1); |
421 __ Ret(); | 421 __ Ret(); |
422 } | 422 } |
423 | 423 |
424 | 424 |
425 // Generate StoreField code, value is passed in a0 register. | 425 // Generate StoreField code, value is passed in a0 register. |
426 // After executing generated code, the receiver_reg and name_reg | 426 // After executing generated code, the receiver_reg and name_reg |
427 // may be clobbered. | 427 // may be clobbered. |
428 void StubCompiler::GenerateStoreField(MacroAssembler* masm, | 428 void StubCompiler::GenerateStoreField(MacroAssembler* masm, |
429 JSObject* object, | 429 Handle<JSObject> object, |
430 int index, | 430 int index, |
431 Map* transition, | 431 Handle<Map> transition, |
432 Register receiver_reg, | 432 Register receiver_reg, |
433 Register name_reg, | 433 Register name_reg, |
434 Register scratch, | 434 Register scratch, |
435 Label* miss_label) { | 435 Label* miss_label) { |
436 // a0 : value. | 436 // a0 : value. |
437 Label exit; | 437 Label exit; |
438 | 438 |
439 // Check that the receiver isn't a smi. | 439 // Check that the receiver isn't a smi. |
440 __ JumpIfSmi(receiver_reg, miss_label, scratch); | 440 __ JumpIfSmi(receiver_reg, miss_label, scratch); |
441 | 441 |
442 // Check that the map of the receiver hasn't changed. | 442 // Check that the map of the receiver hasn't changed. |
443 __ lw(scratch, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); | 443 __ lw(scratch, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); |
444 __ Branch(miss_label, ne, scratch, Operand(Handle<Map>(object->map()))); | 444 __ Branch(miss_label, ne, scratch, Operand(Handle<Map>(object->map()))); |
445 | 445 |
446 // Perform global security token check if needed. | 446 // Perform global security token check if needed. |
447 if (object->IsJSGlobalProxy()) { | 447 if (object->IsJSGlobalProxy()) { |
448 __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label); | 448 __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label); |
449 } | 449 } |
450 | 450 |
451 // Stub never generated for non-global objects that require access | 451 // Stub never generated for non-global objects that require access |
452 // checks. | 452 // checks. |
453 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 453 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
454 | 454 |
455 // Perform map transition for the receiver if necessary. | 455 // Perform map transition for the receiver if necessary. |
456 if ((transition != NULL) && (object->map()->unused_property_fields() == 0)) { | 456 if (!transition.is_null() && (object->map()->unused_property_fields() == 0)) { |
457 // The properties must be extended before we can store the value. | 457 // The properties must be extended before we can store the value. |
458 // We jump to a runtime call that extends the properties array. | 458 // We jump to a runtime call that extends the properties array. |
459 __ push(receiver_reg); | 459 __ push(receiver_reg); |
460 __ li(a2, Operand(Handle<Map>(transition))); | 460 __ li(a2, Operand(transition)); |
461 __ Push(a2, a0); | 461 __ Push(a2, a0); |
462 __ TailCallExternalReference( | 462 __ TailCallExternalReference( |
463 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), | 463 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), |
464 masm->isolate()), | 464 masm->isolate()), |
465 3, 1); | 465 3, 1); |
466 return; | 466 return; |
467 } | 467 } |
468 | 468 |
469 if (transition != NULL) { | 469 if (!transition.is_null()) { |
470 // Update the map of the object; no write barrier updating is | 470 // Update the map of the object; no write barrier updating is |
471 // needed because the map is never in new space. | 471 // needed because the map is never in new space. |
472 __ li(t0, Operand(Handle<Map>(transition))); | 472 __ li(t0, Operand(transition)); |
473 __ sw(t0, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); | 473 __ sw(t0, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); |
474 } | 474 } |
475 | 475 |
476 // Adjust for the number of properties stored in the object. Even in the | 476 // Adjust for the number of properties stored in the object. Even in the |
477 // face of a transition we can use the old map here because the size of the | 477 // face of a transition we can use the old map here because the size of the |
478 // object and the number of in-object properties is not going to change. | 478 // object and the number of in-object properties is not going to change. |
479 index -= object->map()->inobject_properties(); | 479 index -= object->map()->inobject_properties(); |
480 | 480 |
481 if (index < 0) { | 481 if (index < 0) { |
482 // Set the property straight into the object. | 482 // Set the property straight into the object. |
(...skipping 2334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2817 __ bind(&miss); | 2817 __ bind(&miss); |
2818 __ IncrementCounter(counters->call_global_inline_miss(), 1, a1, a3); | 2818 __ IncrementCounter(counters->call_global_inline_miss(), 1, a1, a3); |
2819 MaybeObject* maybe_result = TryGenerateMissBranch(); | 2819 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2820 if (maybe_result->IsFailure()) return maybe_result; | 2820 if (maybe_result->IsFailure()) return maybe_result; |
2821 | 2821 |
2822 // Return the generated code. | 2822 // Return the generated code. |
2823 return TryGetCode(NORMAL, name); | 2823 return TryGetCode(NORMAL, name); |
2824 } | 2824 } |
2825 | 2825 |
2826 | 2826 |
2827 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object, | 2827 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object, |
2828 int index, | 2828 int index, |
2829 Map* transition, | 2829 Handle<Map> transition, |
2830 String* name) { | 2830 Handle<String> name) { |
2831 // ----------- S t a t e ------------- | 2831 // ----------- S t a t e ------------- |
2832 // -- a0 : value | 2832 // -- a0 : value |
2833 // -- a1 : receiver | 2833 // -- a1 : receiver |
2834 // -- a2 : name | 2834 // -- a2 : name |
2835 // -- ra : return address | 2835 // -- ra : return address |
2836 // ----------------------------------- | 2836 // ----------------------------------- |
2837 Label miss; | 2837 Label miss; |
2838 | 2838 |
2839 // Name register might be clobbered. | 2839 // Name register might be clobbered. |
2840 GenerateStoreField(masm(), | 2840 GenerateStoreField(masm(), object, index, transition, a1, a2, a3, &miss); |
2841 object, | |
2842 index, | |
2843 transition, | |
2844 a1, a2, a3, | |
2845 &miss); | |
2846 __ bind(&miss); | 2841 __ bind(&miss); |
2847 __ li(a2, Operand(Handle<String>(name))); // Restore name. | 2842 __ li(a2, Operand(Handle<String>(name))); // Restore name. |
2848 Handle<Code> ic = masm()->isolate()->builtins()->Builtins::StoreIC_Miss(); | 2843 Handle<Code> ic = masm()->isolate()->builtins()->Builtins::StoreIC_Miss(); |
2849 __ Jump(ic, RelocInfo::CODE_TARGET); | 2844 __ Jump(ic, RelocInfo::CODE_TARGET); |
2850 | 2845 |
2851 // Return the generated code. | 2846 // Return the generated code. |
2852 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); | 2847 return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name); |
2853 } | 2848 } |
2854 | 2849 |
2855 | 2850 |
2856 MaybeObject* StoreStubCompiler::CompileStoreCallback(JSObject* object, | 2851 Handle<Code> StoreStubCompiler::CompileStoreCallback( |
2857 AccessorInfo* callback, | 2852 Handle<JSObject> object, |
2858 String* name) { | 2853 Handle<AccessorInfo> callback, |
| 2854 Handle<String> name) { |
2859 // ----------- S t a t e ------------- | 2855 // ----------- S t a t e ------------- |
2860 // -- a0 : value | 2856 // -- a0 : value |
2861 // -- a1 : receiver | 2857 // -- a1 : receiver |
2862 // -- a2 : name | 2858 // -- a2 : name |
2863 // -- ra : return address | 2859 // -- ra : return address |
2864 // ----------------------------------- | 2860 // ----------------------------------- |
2865 Label miss; | 2861 Label miss; |
2866 | 2862 |
2867 // Check that the object isn't a smi. | 2863 // Check that the object isn't a smi. |
2868 __ JumpIfSmi(a1, &miss); | 2864 __ JumpIfSmi(a1, &miss); |
2869 | 2865 |
2870 // Check that the map of the object hasn't changed. | 2866 // Check that the map of the object hasn't changed. |
2871 __ lw(a3, FieldMemOperand(a1, HeapObject::kMapOffset)); | 2867 __ lw(a3, FieldMemOperand(a1, HeapObject::kMapOffset)); |
2872 __ Branch(&miss, ne, a3, Operand(Handle<Map>(object->map()))); | 2868 __ Branch(&miss, ne, a3, Operand(Handle<Map>(object->map()))); |
2873 | 2869 |
2874 // Perform global security token check if needed. | 2870 // Perform global security token check if needed. |
2875 if (object->IsJSGlobalProxy()) { | 2871 if (object->IsJSGlobalProxy()) { |
2876 __ CheckAccessGlobalProxy(a1, a3, &miss); | 2872 __ CheckAccessGlobalProxy(a1, a3, &miss); |
2877 } | 2873 } |
2878 | 2874 |
2879 // Stub never generated for non-global objects that require access | 2875 // Stub never generated for non-global objects that require access |
2880 // checks. | 2876 // checks. |
2881 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 2877 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
2882 | 2878 |
2883 __ push(a1); // Receiver. | 2879 __ push(a1); // Receiver. |
2884 __ li(a3, Operand(Handle<AccessorInfo>(callback))); // Callback info. | 2880 __ li(a3, Operand(callback)); // Callback info. |
2885 __ Push(a3, a2, a0); | 2881 __ Push(a3, a2, a0); |
2886 | 2882 |
2887 // Do tail-call to the runtime system. | 2883 // Do tail-call to the runtime system. |
2888 ExternalReference store_callback_property = | 2884 ExternalReference store_callback_property = |
2889 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), | 2885 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), |
2890 masm()->isolate()); | 2886 masm()->isolate()); |
2891 __ TailCallExternalReference(store_callback_property, 4, 1); | 2887 __ TailCallExternalReference(store_callback_property, 4, 1); |
2892 | 2888 |
2893 // Handle store cache miss. | 2889 // Handle store cache miss. |
2894 __ bind(&miss); | 2890 __ bind(&miss); |
2895 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); | 2891 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); |
2896 __ Jump(ic, RelocInfo::CODE_TARGET); | 2892 __ Jump(ic, RelocInfo::CODE_TARGET); |
2897 | 2893 |
2898 // Return the generated code. | 2894 // Return the generated code. |
2899 return GetCode(CALLBACKS, name); | 2895 return GetCode(CALLBACKS, name); |
2900 } | 2896 } |
2901 | 2897 |
2902 | 2898 |
2903 MaybeObject* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver, | 2899 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( |
2904 String* name) { | 2900 Handle<JSObject> receiver, |
| 2901 Handle<String> name) { |
2905 // ----------- S t a t e ------------- | 2902 // ----------- S t a t e ------------- |
2906 // -- a0 : value | 2903 // -- a0 : value |
2907 // -- a1 : receiver | 2904 // -- a1 : receiver |
2908 // -- a2 : name | 2905 // -- a2 : name |
2909 // -- ra : return address | 2906 // -- ra : return address |
2910 // ----------------------------------- | 2907 // ----------------------------------- |
2911 Label miss; | 2908 Label miss; |
2912 | 2909 |
2913 // Check that the object isn't a smi. | 2910 // Check that the object isn't a smi. |
2914 __ JumpIfSmi(a1, &miss); | 2911 __ JumpIfSmi(a1, &miss); |
(...skipping 25 matching lines...) Expand all Loading... |
2940 // Handle store cache miss. | 2937 // Handle store cache miss. |
2941 __ bind(&miss); | 2938 __ bind(&miss); |
2942 Handle<Code> ic = masm()->isolate()->builtins()->Builtins::StoreIC_Miss(); | 2939 Handle<Code> ic = masm()->isolate()->builtins()->Builtins::StoreIC_Miss(); |
2943 __ Jump(ic, RelocInfo::CODE_TARGET); | 2940 __ Jump(ic, RelocInfo::CODE_TARGET); |
2944 | 2941 |
2945 // Return the generated code. | 2942 // Return the generated code. |
2946 return GetCode(INTERCEPTOR, name); | 2943 return GetCode(INTERCEPTOR, name); |
2947 } | 2944 } |
2948 | 2945 |
2949 | 2946 |
2950 MaybeObject* StoreStubCompiler::CompileStoreGlobal(GlobalObject* object, | 2947 Handle<Code> StoreStubCompiler::CompileStoreGlobal( |
2951 JSGlobalPropertyCell* cell, | 2948 Handle<GlobalObject> object, |
2952 String* name) { | 2949 Handle<JSGlobalPropertyCell> cell, |
| 2950 Handle<String> name) { |
2953 // ----------- S t a t e ------------- | 2951 // ----------- S t a t e ------------- |
2954 // -- a0 : value | 2952 // -- a0 : value |
2955 // -- a1 : receiver | 2953 // -- a1 : receiver |
2956 // -- a2 : name | 2954 // -- a2 : name |
2957 // -- ra : return address | 2955 // -- ra : return address |
2958 // ----------------------------------- | 2956 // ----------------------------------- |
2959 Label miss; | 2957 Label miss; |
2960 | 2958 |
2961 // Check that the map of the global has not changed. | 2959 // Check that the map of the global has not changed. |
2962 __ lw(a3, FieldMemOperand(a1, HeapObject::kMapOffset)); | 2960 __ lw(a3, FieldMemOperand(a1, HeapObject::kMapOffset)); |
2963 __ Branch(&miss, ne, a3, Operand(Handle<Map>(object->map()))); | 2961 __ Branch(&miss, ne, a3, Operand(Handle<Map>(object->map()))); |
2964 | 2962 |
2965 // Check that the value in the cell is not the hole. If it is, this | 2963 // Check that the value in the cell is not the hole. If it is, this |
2966 // cell could have been deleted and reintroducing the global needs | 2964 // cell could have been deleted and reintroducing the global needs |
2967 // to update the property details in the property dictionary of the | 2965 // to update the property details in the property dictionary of the |
2968 // global object. We bail out to the runtime system to do that. | 2966 // global object. We bail out to the runtime system to do that. |
2969 __ li(t0, Operand(Handle<JSGlobalPropertyCell>(cell))); | 2967 __ li(t0, Operand(cell)); |
2970 __ LoadRoot(t1, Heap::kTheHoleValueRootIndex); | 2968 __ LoadRoot(t1, Heap::kTheHoleValueRootIndex); |
2971 __ lw(t2, FieldMemOperand(t0, JSGlobalPropertyCell::kValueOffset)); | 2969 __ lw(t2, FieldMemOperand(t0, JSGlobalPropertyCell::kValueOffset)); |
2972 __ Branch(&miss, eq, t1, Operand(t2)); | 2970 __ Branch(&miss, eq, t1, Operand(t2)); |
2973 | 2971 |
2974 // Store the value in the cell. | 2972 // Store the value in the cell. |
2975 __ sw(a0, FieldMemOperand(t0, JSGlobalPropertyCell::kValueOffset)); | 2973 __ sw(a0, FieldMemOperand(t0, JSGlobalPropertyCell::kValueOffset)); |
2976 __ mov(v0, a0); // Stored value must be returned in v0. | 2974 __ mov(v0, a0); // Stored value must be returned in v0. |
2977 | 2975 |
2978 // This trashes a0 but the value is returned in v0 anyway. | 2976 // This trashes a0 but the value is returned in v0 anyway. |
2979 __ RecordWriteField(t0, | 2977 __ RecordWriteField(t0, |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3125 name, | 3123 name, |
3126 &miss); | 3124 &miss); |
3127 __ bind(&miss); | 3125 __ bind(&miss); |
3128 GenerateLoadMiss(masm(), Code::LOAD_IC); | 3126 GenerateLoadMiss(masm(), Code::LOAD_IC); |
3129 | 3127 |
3130 // Return the generated code. | 3128 // Return the generated code. |
3131 return TryGetCode(INTERCEPTOR, name); | 3129 return TryGetCode(INTERCEPTOR, name); |
3132 } | 3130 } |
3133 | 3131 |
3134 | 3132 |
3135 MaybeObject* LoadStubCompiler::CompileLoadGlobal(JSObject* object, | 3133 Handle<Code> LoadStubCompiler::CompileLoadGlobal( |
3136 GlobalObject* holder, | 3134 Handle<JSObject> object, |
3137 JSGlobalPropertyCell* cell, | 3135 Handle<GlobalObject> holder, |
3138 String* name, | 3136 Handle<JSGlobalPropertyCell> cell, |
3139 bool is_dont_delete) { | 3137 Handle<String> name, |
| 3138 bool is_dont_delete) { |
3140 // ----------- S t a t e ------------- | 3139 // ----------- S t a t e ------------- |
3141 // -- a0 : receiver | 3140 // -- a0 : receiver |
3142 // -- a2 : name | 3141 // -- a2 : name |
3143 // -- ra : return address | 3142 // -- ra : return address |
3144 // ----------------------------------- | 3143 // ----------------------------------- |
3145 Label miss; | 3144 Label miss; |
3146 | 3145 |
3147 // If the object is the holder then we know that it's a global | 3146 // If the object is the holder then we know that it's a global |
3148 // object which can only happen for contextual calls. In this case, | 3147 // object which can only happen for contextual calls. In this case, |
3149 // the receiver cannot be a smi. | 3148 // the receiver cannot be a smi. |
3150 if (object != holder) { | 3149 if (!object.is_identical_to(holder)) { |
3151 __ And(t0, a0, Operand(kSmiTagMask)); | 3150 __ And(t0, a0, Operand(kSmiTagMask)); |
3152 __ Branch(&miss, eq, t0, Operand(zero_reg)); | 3151 __ Branch(&miss, eq, t0, Operand(zero_reg)); |
3153 } | 3152 } |
3154 | 3153 |
3155 // Check that the map of the global has not changed. | 3154 // Check that the map of the global has not changed. |
3156 CheckPrototypes(object, a0, holder, a3, t0, a1, name, &miss); | 3155 CheckPrototypes(object, a0, holder, a3, t0, a1, name, &miss); |
3157 | 3156 |
3158 // Get the value from the cell. | 3157 // Get the value from the cell. |
3159 __ li(a3, Operand(Handle<JSGlobalPropertyCell>(cell))); | 3158 __ li(a3, Operand(cell)); |
3160 __ lw(t0, FieldMemOperand(a3, JSGlobalPropertyCell::kValueOffset)); | 3159 __ lw(t0, FieldMemOperand(a3, JSGlobalPropertyCell::kValueOffset)); |
3161 | 3160 |
3162 // Check for deleted property if property can actually be deleted. | 3161 // Check for deleted property if property can actually be deleted. |
3163 if (!is_dont_delete) { | 3162 if (!is_dont_delete) { |
3164 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 3163 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); |
3165 __ Branch(&miss, eq, t0, Operand(at)); | 3164 __ Branch(&miss, eq, t0, Operand(at)); |
3166 } | 3165 } |
3167 | 3166 |
3168 __ mov(v0, t0); | 3167 __ mov(v0, t0); |
3169 Counters* counters = masm()->isolate()->counters(); | 3168 Counters* counters = masm()->isolate()->counters(); |
3170 __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3); | 3169 __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3); |
3171 __ Ret(); | 3170 __ Ret(); |
3172 | 3171 |
3173 __ bind(&miss); | 3172 __ bind(&miss); |
3174 __ IncrementCounter(counters->named_load_global_stub_miss(), 1, a1, a3); | 3173 __ IncrementCounter(counters->named_load_global_stub_miss(), 1, a1, a3); |
3175 GenerateLoadMiss(masm(), Code::LOAD_IC); | 3174 GenerateLoadMiss(masm(), Code::LOAD_IC); |
3176 | 3175 |
3177 // Return the generated code. | 3176 // Return the generated code. |
3178 return TryGetCode(NORMAL, name); | 3177 return GetCode(NORMAL, name); |
3179 } | 3178 } |
3180 | 3179 |
3181 | 3180 |
3182 Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name, | 3181 Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name, |
3183 Handle<JSObject> receiver, | 3182 Handle<JSObject> receiver, |
3184 Handle<JSObject> holder, | 3183 Handle<JSObject> holder, |
3185 int index) { | 3184 int index) { |
3186 // ----------- S t a t e ------------- | 3185 // ----------- S t a t e ------------- |
3187 // -- ra : return address | 3186 // -- ra : return address |
3188 // -- a0 : key | 3187 // -- a0 : key |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3348 | 3347 |
3349 GenerateLoadFunctionPrototype(masm(), a1, a2, a3, &miss); | 3348 GenerateLoadFunctionPrototype(masm(), a1, a2, a3, &miss); |
3350 __ bind(&miss); | 3349 __ bind(&miss); |
3351 __ DecrementCounter(counters->keyed_load_function_prototype(), 1, a2, a3); | 3350 __ DecrementCounter(counters->keyed_load_function_prototype(), 1, a2, a3); |
3352 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3351 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3353 | 3352 |
3354 return GetCode(CALLBACKS, name); | 3353 return GetCode(CALLBACKS, name); |
3355 } | 3354 } |
3356 | 3355 |
3357 | 3356 |
3358 MaybeObject* KeyedLoadStubCompiler::CompileLoadElement(Map* receiver_map) { | 3357 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement( |
| 3358 Handle<Map> receiver_map) { |
3359 // ----------- S t a t e ------------- | 3359 // ----------- S t a t e ------------- |
3360 // -- ra : return address | 3360 // -- ra : return address |
3361 // -- a0 : key | 3361 // -- a0 : key |
3362 // -- a1 : receiver | 3362 // -- a1 : receiver |
3363 // ----------------------------------- | 3363 // ----------------------------------- |
3364 Code* stub; | |
3365 ElementsKind elements_kind = receiver_map->elements_kind(); | 3364 ElementsKind elements_kind = receiver_map->elements_kind(); |
3366 MaybeObject* maybe_stub = KeyedLoadElementStub(elements_kind).TryGetCode(); | 3365 Handle<Code> stub = KeyedLoadElementStub(elements_kind).GetCode(); |
3367 if (!maybe_stub->To(&stub)) return maybe_stub; | 3366 |
3368 __ DispatchMap(a1, | 3367 __ DispatchMap(a1, a2, receiver_map, stub, DO_SMI_CHECK); |
3369 a2, | |
3370 Handle<Map>(receiver_map), | |
3371 Handle<Code>(stub), | |
3372 DO_SMI_CHECK); | |
3373 | 3368 |
3374 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss(); | 3369 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss(); |
3375 __ Jump(ic, RelocInfo::CODE_TARGET); | 3370 __ Jump(ic, RelocInfo::CODE_TARGET); |
3376 | 3371 |
3377 // Return the generated code. | 3372 // Return the generated code. |
3378 return TryGetCode(NORMAL, NULL); | 3373 return GetCode(NORMAL, factory()->empty_string()); |
3379 } | 3374 } |
3380 | 3375 |
3381 | 3376 |
3382 MaybeObject* KeyedLoadStubCompiler::CompileLoadPolymorphic( | 3377 Handle<Code> KeyedLoadStubCompiler::CompileLoadPolymorphic( |
3383 MapList* receiver_maps, | 3378 MapHandleList* receiver_maps, |
3384 CodeList* handler_ics) { | 3379 CodeHandleList* handler_ics) { |
3385 // ----------- S t a t e ------------- | 3380 // ----------- S t a t e ------------- |
3386 // -- ra : return address | 3381 // -- ra : return address |
3387 // -- a0 : key | 3382 // -- a0 : key |
3388 // -- a1 : receiver | 3383 // -- a1 : receiver |
3389 // ----------------------------------- | 3384 // ----------------------------------- |
3390 Label miss; | 3385 Label miss; |
3391 __ JumpIfSmi(a1, &miss); | 3386 __ JumpIfSmi(a1, &miss); |
3392 | 3387 |
3393 int receiver_count = receiver_maps->length(); | 3388 int receiver_count = receiver_maps->length(); |
3394 __ lw(a2, FieldMemOperand(a1, HeapObject::kMapOffset)); | 3389 __ lw(a2, FieldMemOperand(a1, HeapObject::kMapOffset)); |
3395 for (int current = 0; current < receiver_count; ++current) { | 3390 for (int current = 0; current < receiver_count; ++current) { |
3396 Handle<Map> map(receiver_maps->at(current)); | 3391 __ Jump(handler_ics->at(current), RelocInfo::CODE_TARGET, |
3397 Handle<Code> code(handler_ics->at(current)); | 3392 eq, a2, Operand(receiver_maps->at(current))); |
3398 __ Jump(code, RelocInfo::CODE_TARGET, eq, a2, Operand(map)); | |
3399 } | 3393 } |
3400 | 3394 |
3401 __ bind(&miss); | 3395 __ bind(&miss); |
3402 Handle<Code> miss_ic = isolate()->builtins()->KeyedLoadIC_Miss(); | 3396 Handle<Code> miss_ic = isolate()->builtins()->KeyedLoadIC_Miss(); |
3403 __ Jump(miss_ic, RelocInfo::CODE_TARGET); | 3397 __ Jump(miss_ic, RelocInfo::CODE_TARGET); |
3404 | 3398 |
3405 // Return the generated code. | 3399 // Return the generated code. |
3406 return TryGetCode(NORMAL, NULL, MEGAMORPHIC); | 3400 return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC); |
3407 } | 3401 } |
3408 | 3402 |
3409 | 3403 |
3410 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, | 3404 Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object, |
3411 int index, | 3405 int index, |
3412 Map* transition, | 3406 Handle<Map> transition, |
3413 String* name) { | 3407 Handle<String> name) { |
3414 // ----------- S t a t e ------------- | 3408 // ----------- S t a t e ------------- |
3415 // -- a0 : value | 3409 // -- a0 : value |
3416 // -- a1 : key | 3410 // -- a1 : key |
3417 // -- a2 : receiver | 3411 // -- a2 : receiver |
3418 // -- ra : return address | 3412 // -- ra : return address |
3419 // ----------------------------------- | 3413 // ----------------------------------- |
3420 | 3414 |
3421 Label miss; | 3415 Label miss; |
3422 | 3416 |
3423 Counters* counters = masm()->isolate()->counters(); | 3417 Counters* counters = masm()->isolate()->counters(); |
3424 __ IncrementCounter(counters->keyed_store_field(), 1, a3, t0); | 3418 __ IncrementCounter(counters->keyed_store_field(), 1, a3, t0); |
3425 | 3419 |
3426 // Check that the name has not changed. | 3420 // Check that the name has not changed. |
3427 __ Branch(&miss, ne, a1, Operand(Handle<String>(name))); | 3421 __ Branch(&miss, ne, a1, Operand(name)); |
3428 | 3422 |
3429 // a3 is used as scratch register. a1 and a2 keep their values if a jump to | 3423 // a3 is used as scratch register. a1 and a2 keep their values if a jump to |
3430 // the miss label is generated. | 3424 // the miss label is generated. |
3431 GenerateStoreField(masm(), | 3425 GenerateStoreField(masm(), object, index, transition, a2, a1, a3, &miss); |
3432 object, | |
3433 index, | |
3434 transition, | |
3435 a2, a1, a3, | |
3436 &miss); | |
3437 __ bind(&miss); | 3426 __ bind(&miss); |
3438 | 3427 |
3439 __ DecrementCounter(counters->keyed_store_field(), 1, a3, t0); | 3428 __ DecrementCounter(counters->keyed_store_field(), 1, a3, t0); |
3440 Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss(); | 3429 Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss(); |
3441 __ Jump(ic, RelocInfo::CODE_TARGET); | 3430 __ Jump(ic, RelocInfo::CODE_TARGET); |
3442 | 3431 |
3443 // Return the generated code. | 3432 // Return the generated code. |
3444 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); | 3433 return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name); |
3445 } | 3434 } |
3446 | 3435 |
3447 | 3436 |
3448 MaybeObject* KeyedStoreStubCompiler::CompileStoreElement(Map* receiver_map) { | 3437 Handle<Code> KeyedStoreStubCompiler::CompileStoreElement( |
| 3438 Handle<Map> receiver_map) { |
3449 // ----------- S t a t e ------------- | 3439 // ----------- S t a t e ------------- |
3450 // -- a0 : value | 3440 // -- a0 : value |
3451 // -- a1 : key | 3441 // -- a1 : key |
3452 // -- a2 : receiver | 3442 // -- a2 : receiver |
3453 // -- ra : return address | 3443 // -- ra : return address |
3454 // -- a3 : scratch | 3444 // -- a3 : scratch |
3455 // ----------------------------------- | 3445 // ----------------------------------- |
3456 Code* stub; | |
3457 ElementsKind elements_kind = receiver_map->elements_kind(); | 3446 ElementsKind elements_kind = receiver_map->elements_kind(); |
3458 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; | 3447 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; |
3459 MaybeObject* maybe_stub = | 3448 Handle<Code> stub = |
3460 KeyedStoreElementStub(is_js_array, elements_kind).TryGetCode(); | 3449 KeyedStoreElementStub(is_js_array, elements_kind).GetCode(); |
3461 if (!maybe_stub->To(&stub)) return maybe_stub; | 3450 |
3462 __ DispatchMap(a2, | 3451 __ DispatchMap(a2, a3, receiver_map, stub, DO_SMI_CHECK); |
3463 a3, | |
3464 Handle<Map>(receiver_map), | |
3465 Handle<Code>(stub), | |
3466 DO_SMI_CHECK); | |
3467 | 3452 |
3468 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); | 3453 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); |
3469 __ Jump(ic, RelocInfo::CODE_TARGET); | 3454 __ Jump(ic, RelocInfo::CODE_TARGET); |
3470 | 3455 |
3471 // Return the generated code. | 3456 // Return the generated code. |
3472 return GetCode(NORMAL, NULL); | 3457 return GetCode(NORMAL, factory()->empty_string()); |
3473 } | 3458 } |
3474 | 3459 |
3475 | 3460 |
3476 MaybeObject* KeyedStoreStubCompiler::CompileStorePolymorphic( | 3461 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( |
3477 MapList* receiver_maps, | 3462 MapHandleList* receiver_maps, |
3478 CodeList* handler_stubs, | 3463 CodeHandleList* handler_stubs, |
3479 MapList* transitioned_maps) { | 3464 MapHandleList* transitioned_maps) { |
3480 // ----------- S t a t e ------------- | 3465 // ----------- S t a t e ------------- |
3481 // -- a0 : value | 3466 // -- a0 : value |
3482 // -- a1 : key | 3467 // -- a1 : key |
3483 // -- a2 : receiver | 3468 // -- a2 : receiver |
3484 // -- ra : return address | 3469 // -- ra : return address |
3485 // -- a3 : scratch | 3470 // -- a3 : scratch |
3486 // ----------------------------------- | 3471 // ----------------------------------- |
3487 Label miss; | 3472 Label miss; |
3488 __ JumpIfSmi(a2, &miss); | 3473 __ JumpIfSmi(a2, &miss); |
3489 | 3474 |
3490 int receiver_count = receiver_maps->length(); | 3475 int receiver_count = receiver_maps->length(); |
3491 __ lw(a3, FieldMemOperand(a2, HeapObject::kMapOffset)); | 3476 __ lw(a3, FieldMemOperand(a2, HeapObject::kMapOffset)); |
3492 for (int i = 0; i < receiver_count; ++i) { | 3477 for (int i = 0; i < receiver_count; ++i) { |
3493 Handle<Map> map(receiver_maps->at(i)); | 3478 if (transitioned_maps->at(i).is_null()) { |
3494 Handle<Code> code(handler_stubs->at(i)); | 3479 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, eq, |
3495 if (transitioned_maps->at(i) == NULL) { | 3480 a3, Operand(receiver_maps->at(i))); |
3496 __ Jump(code, RelocInfo::CODE_TARGET, eq, a3, Operand(map)); | |
3497 } else { | 3481 } else { |
3498 Label next_map; | 3482 Label next_map; |
3499 __ Branch(&next_map, ne, a3, Operand(map)); | 3483 __ Branch(&next_map, ne, a3, Operand(receiver_maps->at(i))); |
3500 __ li(a3, Operand(Handle<Map>(transitioned_maps->at(i)))); | 3484 __ li(a3, Operand(transitioned_maps->at(i))); |
3501 __ Jump(code, RelocInfo::CODE_TARGET); | 3485 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET); |
3502 __ bind(&next_map); | 3486 __ bind(&next_map); |
3503 } | 3487 } |
3504 } | 3488 } |
3505 | 3489 |
3506 __ bind(&miss); | 3490 __ bind(&miss); |
3507 Handle<Code> miss_ic = isolate()->builtins()->KeyedStoreIC_Miss(); | 3491 Handle<Code> miss_ic = isolate()->builtins()->KeyedStoreIC_Miss(); |
3508 __ Jump(miss_ic, RelocInfo::CODE_TARGET); | 3492 __ Jump(miss_ic, RelocInfo::CODE_TARGET); |
3509 | 3493 |
3510 // Return the generated code. | 3494 // Return the generated code. |
3511 return GetCode(NORMAL, NULL, MEGAMORPHIC); | 3495 return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC); |
3512 } | 3496 } |
3513 | 3497 |
3514 | 3498 |
3515 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { | 3499 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { |
3516 // a0 : argc | 3500 // a0 : argc |
3517 // a1 : constructor | 3501 // a1 : constructor |
3518 // ra : return address | 3502 // ra : return address |
3519 // [sp] : last argument | 3503 // [sp] : last argument |
3520 Label generic_stub_call; | 3504 Label generic_stub_call; |
3521 | 3505 |
(...skipping 1205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4727 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); | 4711 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); |
4728 __ Jump(ic_miss, RelocInfo::CODE_TARGET); | 4712 __ Jump(ic_miss, RelocInfo::CODE_TARGET); |
4729 } | 4713 } |
4730 | 4714 |
4731 | 4715 |
4732 #undef __ | 4716 #undef __ |
4733 | 4717 |
4734 } } // namespace v8::internal | 4718 } } // namespace v8::internal |
4735 | 4719 |
4736 #endif // V8_TARGET_ARCH_MIPS | 4720 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |