| 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 736 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 747 | 747 |
| 748 StubCompiler* stub_compiler_; | 748 StubCompiler* stub_compiler_; |
| 749 const ParameterCount& arguments_; | 749 const ParameterCount& arguments_; |
| 750 Register name_; | 750 Register name_; |
| 751 Code::ExtraICState extra_state_; | 751 Code::ExtraICState extra_state_; |
| 752 }; | 752 }; |
| 753 | 753 |
| 754 | 754 |
| 755 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { | 755 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { |
| 756 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); | 756 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); |
| 757 Code* code = NULL; | 757 Handle<Code> code = (kind == Code::LOAD_IC) |
| 758 if (kind == Code::LOAD_IC) { | 758 ? masm->isolate()->builtins()->LoadIC_Miss() |
| 759 code = masm->isolate()->builtins()->builtin(Builtins::kLoadIC_Miss); | 759 : masm->isolate()->builtins()->KeyedLoadIC_Miss(); |
| 760 } else { | 760 __ jmp(code, RelocInfo::CODE_TARGET); |
| 761 code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss); | |
| 762 } | |
| 763 | |
| 764 Handle<Code> ic(code); | |
| 765 __ jmp(ic, RelocInfo::CODE_TARGET); | |
| 766 } | 761 } |
| 767 | 762 |
| 768 | 763 |
| 769 void StubCompiler::GenerateKeyedLoadMissForceGeneric(MacroAssembler* masm) { | 764 void StubCompiler::GenerateKeyedLoadMissForceGeneric(MacroAssembler* masm) { |
| 770 Code* code = masm->isolate()->builtins()->builtin( | 765 Code* code = masm->isolate()->builtins()->builtin( |
| 771 Builtins::kKeyedLoadIC_MissForceGeneric); | 766 Builtins::kKeyedLoadIC_MissForceGeneric); |
| 772 Handle<Code> ic(code); | 767 Handle<Code> ic(code); |
| 773 __ jmp(ic, RelocInfo::CODE_TARGET); | 768 __ jmp(ic, RelocInfo::CODE_TARGET); |
| 774 } | 769 } |
| 775 | 770 |
| (...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1212 name, | 1207 name, |
| 1213 scratch1, | 1208 scratch1, |
| 1214 miss); | 1209 miss); |
| 1215 if (result->IsFailure()) set_failure(Failure::cast(result)); | 1210 if (result->IsFailure()) set_failure(Failure::cast(result)); |
| 1216 | 1211 |
| 1217 // Return the register containing the holder. | 1212 // Return the register containing the holder. |
| 1218 return reg; | 1213 return reg; |
| 1219 } | 1214 } |
| 1220 | 1215 |
| 1221 | 1216 |
| 1222 void StubCompiler::GenerateLoadField(JSObject* object, | 1217 void StubCompiler::GenerateLoadField(Handle<JSObject> object, |
| 1223 JSObject* holder, | 1218 Handle<JSObject> holder, |
| 1224 Register receiver, | 1219 Register receiver, |
| 1225 Register scratch1, | 1220 Register scratch1, |
| 1226 Register scratch2, | 1221 Register scratch2, |
| 1227 Register scratch3, | 1222 Register scratch3, |
| 1228 int index, | 1223 int index, |
| 1229 String* name, | 1224 Handle<String> name, |
| 1230 Label* miss) { | 1225 Label* miss) { |
| 1231 // Check that the receiver isn't a smi. | 1226 // Check that the receiver isn't a smi. |
| 1232 __ JumpIfSmi(receiver, miss); | 1227 __ JumpIfSmi(receiver, miss); |
| 1233 | 1228 |
| 1234 // Check the prototype chain. | 1229 // Check the prototype chain. |
| 1235 Register reg = | 1230 Register reg = CheckPrototypes( |
| 1236 CheckPrototypes(object, receiver, holder, | 1231 object, receiver, holder, scratch1, scratch2, scratch3, name, miss); |
| 1237 scratch1, scratch2, scratch3, name, miss); | |
| 1238 | 1232 |
| 1239 // Get the value from the properties. | 1233 // Get the value from the properties. |
| 1240 GenerateFastPropertyLoad(masm(), eax, reg, Handle<JSObject>(holder), index); | 1234 GenerateFastPropertyLoad(masm(), eax, reg, holder, index); |
| 1241 __ ret(0); | 1235 __ ret(0); |
| 1242 } | 1236 } |
| 1243 | 1237 |
| 1244 | 1238 |
| 1245 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object, | 1239 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object, |
| 1246 JSObject* holder, | 1240 JSObject* holder, |
| 1247 Register receiver, | 1241 Register receiver, |
| 1248 Register name_reg, | 1242 Register name_reg, |
| 1249 Register scratch1, | 1243 Register scratch1, |
| 1250 Register scratch2, | 1244 Register scratch2, |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1302 __ mov(ApiParameterOperand(1), ebx); // arguments pointer. | 1296 __ mov(ApiParameterOperand(1), ebx); // arguments pointer. |
| 1303 | 1297 |
| 1304 // Emitting a stub call may try to allocate (if the code is not | 1298 // Emitting a stub call may try to allocate (if the code is not |
| 1305 // already generated). Do not allow the assembler to perform a | 1299 // already generated). Do not allow the assembler to perform a |
| 1306 // garbage collection but instead return the allocation failure | 1300 // garbage collection but instead return the allocation failure |
| 1307 // object. | 1301 // object. |
| 1308 return masm()->TryCallApiFunctionAndReturn(&fun, kStackSpace); | 1302 return masm()->TryCallApiFunctionAndReturn(&fun, kStackSpace); |
| 1309 } | 1303 } |
| 1310 | 1304 |
| 1311 | 1305 |
| 1312 void StubCompiler::GenerateLoadConstant(JSObject* object, | 1306 void StubCompiler::GenerateLoadConstant(Handle<JSObject> object, |
| 1313 JSObject* holder, | 1307 Handle<JSObject> holder, |
| 1314 Register receiver, | 1308 Register receiver, |
| 1315 Register scratch1, | 1309 Register scratch1, |
| 1316 Register scratch2, | 1310 Register scratch2, |
| 1317 Register scratch3, | 1311 Register scratch3, |
| 1318 Object* value, | 1312 Handle<Object> value, |
| 1319 String* name, | 1313 Handle<String> name, |
| 1320 Label* miss) { | 1314 Label* miss) { |
| 1321 // Check that the receiver isn't a smi. | 1315 // Check that the receiver isn't a smi. |
| 1322 __ JumpIfSmi(receiver, miss); | 1316 __ JumpIfSmi(receiver, miss); |
| 1323 | 1317 |
| 1324 // Check that the maps haven't changed. | 1318 // Check that the maps haven't changed. |
| 1325 CheckPrototypes(object, receiver, holder, | 1319 CheckPrototypes( |
| 1326 scratch1, scratch2, scratch3, name, miss); | 1320 object, receiver, holder, scratch1, scratch2, scratch3, name, miss); |
| 1327 | 1321 |
| 1328 // Return the constant value. | 1322 // Return the constant value. |
| 1329 __ mov(eax, Handle<Object>(value)); | 1323 __ mov(eax, value); |
| 1330 __ ret(0); | 1324 __ ret(0); |
| 1331 } | 1325 } |
| 1332 | 1326 |
| 1333 | 1327 |
| 1334 void StubCompiler::GenerateLoadInterceptor(JSObject* object, | 1328 void StubCompiler::GenerateLoadInterceptor(JSObject* object, |
| 1335 JSObject* interceptor_holder, | 1329 JSObject* interceptor_holder, |
| 1336 LookupResult* lookup, | 1330 LookupResult* lookup, |
| 1337 Register receiver, | 1331 Register receiver, |
| 1338 Register name_reg, | 1332 Register name_reg, |
| 1339 Register scratch1, | 1333 Register scratch1, |
| (...skipping 1649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2989 } | 2983 } |
| 2990 __ bind(&miss); | 2984 __ bind(&miss); |
| 2991 Handle<Code> miss_ic = isolate()->builtins()->KeyedStoreIC_Miss(); | 2985 Handle<Code> miss_ic = isolate()->builtins()->KeyedStoreIC_Miss(); |
| 2992 __ jmp(miss_ic, RelocInfo::CODE_TARGET); | 2986 __ jmp(miss_ic, RelocInfo::CODE_TARGET); |
| 2993 | 2987 |
| 2994 // Return the generated code. | 2988 // Return the generated code. |
| 2995 return GetCode(NORMAL, NULL, MEGAMORPHIC); | 2989 return GetCode(NORMAL, NULL, MEGAMORPHIC); |
| 2996 } | 2990 } |
| 2997 | 2991 |
| 2998 | 2992 |
| 2999 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, | 2993 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<String> name, |
| 3000 JSObject* object, | 2994 Handle<JSObject> object, |
| 3001 JSObject* last) { | 2995 Handle<JSObject> last) { |
| 3002 // ----------- S t a t e ------------- | 2996 // ----------- S t a t e ------------- |
| 3003 // -- eax : receiver | 2997 // -- eax : receiver |
| 3004 // -- ecx : name | 2998 // -- ecx : name |
| 3005 // -- esp[0] : return address | 2999 // -- esp[0] : return address |
| 3006 // ----------------------------------- | 3000 // ----------------------------------- |
| 3007 Label miss; | 3001 Label miss; |
| 3008 | 3002 |
| 3009 // Check that the receiver isn't a smi. | 3003 // Check that the receiver isn't a smi. |
| 3010 __ JumpIfSmi(eax, &miss); | 3004 __ JumpIfSmi(eax, &miss); |
| 3011 | 3005 |
| 3012 ASSERT(last->IsGlobalObject() || last->HasFastProperties()); | 3006 ASSERT(last->IsGlobalObject() || last->HasFastProperties()); |
| 3013 | 3007 |
| 3014 // Check the maps of the full prototype chain. Also check that | 3008 // Check the maps of the full prototype chain. Also check that |
| 3015 // global property cells up to (but not including) the last object | 3009 // global property cells up to (but not including) the last object |
| 3016 // in the prototype chain are empty. | 3010 // in the prototype chain are empty. |
| 3017 CheckPrototypes(object, eax, last, ebx, edx, edi, name, &miss); | 3011 CheckPrototypes(object, eax, last, ebx, edx, edi, name, &miss); |
| 3018 | 3012 |
| 3019 // If the last object in the prototype chain is a global object, | 3013 // If the last object in the prototype chain is a global object, |
| 3020 // check that the global property cell is empty. | 3014 // check that the global property cell is empty. |
| 3021 if (last->IsGlobalObject()) { | 3015 if (last->IsGlobalObject()) { |
| 3022 MaybeObject* cell = TryGenerateCheckPropertyCell(masm(), | 3016 GenerateCheckPropertyCell( |
| 3023 GlobalObject::cast(last), | 3017 masm(), Handle<GlobalObject>::cast(last), name, edx, &miss); |
| 3024 name, | |
| 3025 edx, | |
| 3026 &miss); | |
| 3027 if (cell->IsFailure()) { | |
| 3028 miss.Unuse(); | |
| 3029 return cell; | |
| 3030 } | |
| 3031 } | 3018 } |
| 3032 | 3019 |
| 3033 // Return undefined if maps of the full prototype chain are still the | 3020 // Return undefined if maps of the full prototype chain are still the |
| 3034 // same and no global property with this name contains a value. | 3021 // same and no global property with this name contains a value. |
| 3035 __ mov(eax, isolate()->factory()->undefined_value()); | 3022 __ mov(eax, isolate()->factory()->undefined_value()); |
| 3036 __ ret(0); | 3023 __ ret(0); |
| 3037 | 3024 |
| 3038 __ bind(&miss); | 3025 __ bind(&miss); |
| 3039 GenerateLoadMiss(masm(), Code::LOAD_IC); | 3026 GenerateLoadMiss(masm(), Code::LOAD_IC); |
| 3040 | 3027 |
| 3041 // Return the generated code. | 3028 // Return the generated code. |
| 3042 return GetCode(NONEXISTENT, isolate()->heap()->empty_string()); | 3029 return GetCode(NONEXISTENT, factory()->empty_string()); |
| 3043 } | 3030 } |
| 3044 | 3031 |
| 3045 | 3032 |
| 3046 MaybeObject* LoadStubCompiler::CompileLoadField(JSObject* object, | 3033 Handle<Code> LoadStubCompiler::CompileLoadField(Handle<JSObject> object, |
| 3047 JSObject* holder, | 3034 Handle<JSObject> holder, |
| 3048 int index, | 3035 int index, |
| 3049 String* name) { | 3036 Handle<String> name) { |
| 3050 // ----------- S t a t e ------------- | 3037 // ----------- S t a t e ------------- |
| 3051 // -- eax : receiver | 3038 // -- eax : receiver |
| 3052 // -- ecx : name | 3039 // -- ecx : name |
| 3053 // -- esp[0] : return address | 3040 // -- esp[0] : return address |
| 3054 // ----------------------------------- | 3041 // ----------------------------------- |
| 3055 Label miss; | 3042 Label miss; |
| 3056 | 3043 |
| 3057 GenerateLoadField(object, holder, eax, ebx, edx, edi, index, name, &miss); | 3044 GenerateLoadField(object, holder, eax, ebx, edx, edi, index, name, &miss); |
| 3058 __ bind(&miss); | 3045 __ bind(&miss); |
| 3059 GenerateLoadMiss(masm(), Code::LOAD_IC); | 3046 GenerateLoadMiss(masm(), Code::LOAD_IC); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 3078 edi, callback, name, &miss); | 3065 edi, callback, name, &miss); |
| 3079 if (result->IsFailure()) { | 3066 if (result->IsFailure()) { |
| 3080 miss.Unuse(); | 3067 miss.Unuse(); |
| 3081 return result; | 3068 return result; |
| 3082 } | 3069 } |
| 3083 | 3070 |
| 3084 __ bind(&miss); | 3071 __ bind(&miss); |
| 3085 GenerateLoadMiss(masm(), Code::LOAD_IC); | 3072 GenerateLoadMiss(masm(), Code::LOAD_IC); |
| 3086 | 3073 |
| 3087 // Return the generated code. | 3074 // Return the generated code. |
| 3088 return GetCode(CALLBACKS, name); | 3075 return TryGetCode(CALLBACKS, name); |
| 3089 } | 3076 } |
| 3090 | 3077 |
| 3091 | 3078 |
| 3092 MaybeObject* LoadStubCompiler::CompileLoadConstant(JSObject* object, | 3079 Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object, |
| 3093 JSObject* holder, | 3080 Handle<JSObject> holder, |
| 3094 Object* value, | 3081 Handle<Object> value, |
| 3095 String* name) { | 3082 Handle<String> name) { |
| 3096 // ----------- S t a t e ------------- | 3083 // ----------- S t a t e ------------- |
| 3097 // -- eax : receiver | 3084 // -- eax : receiver |
| 3098 // -- ecx : name | 3085 // -- ecx : name |
| 3099 // -- esp[0] : return address | 3086 // -- esp[0] : return address |
| 3100 // ----------------------------------- | 3087 // ----------------------------------- |
| 3101 Label miss; | 3088 Label miss; |
| 3102 | 3089 |
| 3103 GenerateLoadConstant(object, holder, eax, ebx, edx, edi, value, name, &miss); | 3090 GenerateLoadConstant(object, holder, eax, ebx, edx, edi, value, name, &miss); |
| 3104 __ bind(&miss); | 3091 __ bind(&miss); |
| 3105 GenerateLoadMiss(masm(), Code::LOAD_IC); | 3092 GenerateLoadMiss(masm(), Code::LOAD_IC); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 3132 edx, | 3119 edx, |
| 3133 ebx, | 3120 ebx, |
| 3134 edi, | 3121 edi, |
| 3135 name, | 3122 name, |
| 3136 &miss); | 3123 &miss); |
| 3137 | 3124 |
| 3138 __ bind(&miss); | 3125 __ bind(&miss); |
| 3139 GenerateLoadMiss(masm(), Code::LOAD_IC); | 3126 GenerateLoadMiss(masm(), Code::LOAD_IC); |
| 3140 | 3127 |
| 3141 // Return the generated code. | 3128 // Return the generated code. |
| 3142 return GetCode(INTERCEPTOR, name); | 3129 return TryGetCode(INTERCEPTOR, name); |
| 3143 } | 3130 } |
| 3144 | 3131 |
| 3145 | 3132 |
| 3146 MaybeObject* LoadStubCompiler::CompileLoadGlobal(JSObject* object, | 3133 MaybeObject* LoadStubCompiler::CompileLoadGlobal(JSObject* object, |
| 3147 GlobalObject* holder, | 3134 GlobalObject* holder, |
| 3148 JSGlobalPropertyCell* cell, | 3135 JSGlobalPropertyCell* cell, |
| 3149 String* name, | 3136 String* name, |
| 3150 bool is_dont_delete) { | 3137 bool is_dont_delete) { |
| 3151 // ----------- S t a t e ------------- | 3138 // ----------- S t a t e ------------- |
| 3152 // -- eax : receiver | 3139 // -- eax : receiver |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3185 Counters* counters = isolate()->counters(); | 3172 Counters* counters = isolate()->counters(); |
| 3186 __ IncrementCounter(counters->named_load_global_stub(), 1); | 3173 __ IncrementCounter(counters->named_load_global_stub(), 1); |
| 3187 __ mov(eax, ebx); | 3174 __ mov(eax, ebx); |
| 3188 __ ret(0); | 3175 __ ret(0); |
| 3189 | 3176 |
| 3190 __ bind(&miss); | 3177 __ bind(&miss); |
| 3191 __ IncrementCounter(counters->named_load_global_stub_miss(), 1); | 3178 __ IncrementCounter(counters->named_load_global_stub_miss(), 1); |
| 3192 GenerateLoadMiss(masm(), Code::LOAD_IC); | 3179 GenerateLoadMiss(masm(), Code::LOAD_IC); |
| 3193 | 3180 |
| 3194 // Return the generated code. | 3181 // Return the generated code. |
| 3195 return GetCode(NORMAL, name); | 3182 return TryGetCode(NORMAL, name); |
| 3196 } | 3183 } |
| 3197 | 3184 |
| 3198 | 3185 |
| 3199 MaybeObject* KeyedLoadStubCompiler::CompileLoadField(String* name, | 3186 Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name, |
| 3200 JSObject* receiver, | 3187 Handle<JSObject> receiver, |
| 3201 JSObject* holder, | 3188 Handle<JSObject> holder, |
| 3202 int index) { | 3189 int index) { |
| 3203 // ----------- S t a t e ------------- | 3190 // ----------- S t a t e ------------- |
| 3204 // -- eax : key | 3191 // -- eax : key |
| 3205 // -- edx : receiver | 3192 // -- edx : receiver |
| 3206 // -- esp[0] : return address | 3193 // -- esp[0] : return address |
| 3207 // ----------------------------------- | 3194 // ----------------------------------- |
| 3208 Label miss; | 3195 Label miss; |
| 3209 | 3196 |
| 3210 Counters* counters = isolate()->counters(); | 3197 Counters* counters = isolate()->counters(); |
| 3211 __ IncrementCounter(counters->keyed_load_field(), 1); | 3198 __ IncrementCounter(counters->keyed_load_field(), 1); |
| 3212 | 3199 |
| 3213 // Check that the name has not changed. | 3200 // Check that the name has not changed. |
| 3214 __ cmp(eax, Immediate(Handle<String>(name))); | 3201 __ cmp(eax, Immediate(name)); |
| 3215 __ j(not_equal, &miss); | 3202 __ j(not_equal, &miss); |
| 3216 | 3203 |
| 3217 GenerateLoadField(receiver, holder, edx, ebx, ecx, edi, index, name, &miss); | 3204 GenerateLoadField(receiver, holder, edx, ebx, ecx, edi, index, name, &miss); |
| 3218 | 3205 |
| 3219 __ bind(&miss); | 3206 __ bind(&miss); |
| 3220 __ DecrementCounter(counters->keyed_load_field(), 1); | 3207 __ DecrementCounter(counters->keyed_load_field(), 1); |
| 3221 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3208 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 3222 | 3209 |
| 3223 // Return the generated code. | 3210 // Return the generated code. |
| 3224 return GetCode(FIELD, name); | 3211 return GetCode(FIELD, name); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 3250 miss.Unuse(); | 3237 miss.Unuse(); |
| 3251 return result; | 3238 return result; |
| 3252 } | 3239 } |
| 3253 | 3240 |
| 3254 __ bind(&miss); | 3241 __ bind(&miss); |
| 3255 | 3242 |
| 3256 __ DecrementCounter(counters->keyed_load_callback(), 1); | 3243 __ DecrementCounter(counters->keyed_load_callback(), 1); |
| 3257 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3244 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 3258 | 3245 |
| 3259 // Return the generated code. | 3246 // Return the generated code. |
| 3260 return GetCode(CALLBACKS, name); | 3247 return TryGetCode(CALLBACKS, name); |
| 3261 } | 3248 } |
| 3262 | 3249 |
| 3263 | 3250 |
| 3264 MaybeObject* KeyedLoadStubCompiler::CompileLoadConstant(String* name, | 3251 Handle<Code> KeyedLoadStubCompiler::CompileLoadConstant( |
| 3265 JSObject* receiver, | 3252 Handle<String> name, |
| 3266 JSObject* holder, | 3253 Handle<JSObject> receiver, |
| 3267 Object* value) { | 3254 Handle<JSObject> holder, |
| 3255 Handle<Object> value) { |
| 3268 // ----------- S t a t e ------------- | 3256 // ----------- S t a t e ------------- |
| 3269 // -- eax : key | 3257 // -- eax : key |
| 3270 // -- edx : receiver | 3258 // -- edx : receiver |
| 3271 // -- esp[0] : return address | 3259 // -- esp[0] : return address |
| 3272 // ----------------------------------- | 3260 // ----------------------------------- |
| 3273 Label miss; | 3261 Label miss; |
| 3274 | 3262 |
| 3275 Counters* counters = isolate()->counters(); | 3263 Counters* counters = isolate()->counters(); |
| 3276 __ IncrementCounter(counters->keyed_load_constant_function(), 1); | 3264 __ IncrementCounter(counters->keyed_load_constant_function(), 1); |
| 3277 | 3265 |
| 3278 // Check that the name has not changed. | 3266 // Check that the name has not changed. |
| 3279 __ cmp(eax, Immediate(Handle<String>(name))); | 3267 __ cmp(eax, Immediate(name)); |
| 3280 __ j(not_equal, &miss); | 3268 __ j(not_equal, &miss); |
| 3281 | 3269 |
| 3282 GenerateLoadConstant(receiver, holder, edx, ebx, ecx, edi, | 3270 GenerateLoadConstant( |
| 3283 value, name, &miss); | 3271 receiver, holder, edx, ebx, ecx, edi, value, name, &miss); |
| 3284 __ bind(&miss); | 3272 __ bind(&miss); |
| 3285 __ DecrementCounter(counters->keyed_load_constant_function(), 1); | 3273 __ DecrementCounter(counters->keyed_load_constant_function(), 1); |
| 3286 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3274 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 3287 | 3275 |
| 3288 // Return the generated code. | 3276 // Return the generated code. |
| 3289 return GetCode(CONSTANT_FUNCTION, name); | 3277 return GetCode(CONSTANT_FUNCTION, name); |
| 3290 } | 3278 } |
| 3291 | 3279 |
| 3292 | 3280 |
| 3293 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, | 3281 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, |
| (...skipping 23 matching lines...) Expand all Loading... |
| 3317 ecx, | 3305 ecx, |
| 3318 ebx, | 3306 ebx, |
| 3319 edi, | 3307 edi, |
| 3320 name, | 3308 name, |
| 3321 &miss); | 3309 &miss); |
| 3322 __ bind(&miss); | 3310 __ bind(&miss); |
| 3323 __ DecrementCounter(counters->keyed_load_interceptor(), 1); | 3311 __ DecrementCounter(counters->keyed_load_interceptor(), 1); |
| 3324 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3312 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 3325 | 3313 |
| 3326 // Return the generated code. | 3314 // Return the generated code. |
| 3327 return GetCode(INTERCEPTOR, name); | 3315 return TryGetCode(INTERCEPTOR, name); |
| 3328 } | 3316 } |
| 3329 | 3317 |
| 3330 | 3318 |
| 3331 MaybeObject* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { | 3319 Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength( |
| 3320 Handle<String> name) { |
| 3332 // ----------- S t a t e ------------- | 3321 // ----------- S t a t e ------------- |
| 3333 // -- eax : key | 3322 // -- eax : key |
| 3334 // -- edx : receiver | 3323 // -- edx : receiver |
| 3335 // -- esp[0] : return address | 3324 // -- esp[0] : return address |
| 3336 // ----------------------------------- | 3325 // ----------------------------------- |
| 3337 Label miss; | 3326 Label miss; |
| 3338 | 3327 |
| 3339 Counters* counters = isolate()->counters(); | 3328 Counters* counters = isolate()->counters(); |
| 3340 __ IncrementCounter(counters->keyed_load_array_length(), 1); | 3329 __ IncrementCounter(counters->keyed_load_array_length(), 1); |
| 3341 | 3330 |
| 3342 // Check that the name has not changed. | 3331 // Check that the name has not changed. |
| 3343 __ cmp(eax, Immediate(Handle<String>(name))); | 3332 __ cmp(eax, Immediate(name)); |
| 3344 __ j(not_equal, &miss); | 3333 __ j(not_equal, &miss); |
| 3345 | 3334 |
| 3346 GenerateLoadArrayLength(masm(), edx, ecx, &miss); | 3335 GenerateLoadArrayLength(masm(), edx, ecx, &miss); |
| 3347 __ bind(&miss); | 3336 __ bind(&miss); |
| 3348 __ DecrementCounter(counters->keyed_load_array_length(), 1); | 3337 __ DecrementCounter(counters->keyed_load_array_length(), 1); |
| 3349 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3338 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 3350 | 3339 |
| 3351 // Return the generated code. | 3340 // Return the generated code. |
| 3352 return GetCode(CALLBACKS, name); | 3341 return GetCode(CALLBACKS, name); |
| 3353 } | 3342 } |
| 3354 | 3343 |
| 3355 | 3344 |
| 3356 MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { | 3345 Handle<Code> KeyedLoadStubCompiler::CompileLoadStringLength( |
| 3346 Handle<String> name) { |
| 3357 // ----------- S t a t e ------------- | 3347 // ----------- S t a t e ------------- |
| 3358 // -- eax : key | 3348 // -- eax : key |
| 3359 // -- edx : receiver | 3349 // -- edx : receiver |
| 3360 // -- esp[0] : return address | 3350 // -- esp[0] : return address |
| 3361 // ----------------------------------- | 3351 // ----------------------------------- |
| 3362 Label miss; | 3352 Label miss; |
| 3363 | 3353 |
| 3364 Counters* counters = isolate()->counters(); | 3354 Counters* counters = isolate()->counters(); |
| 3365 __ IncrementCounter(counters->keyed_load_string_length(), 1); | 3355 __ IncrementCounter(counters->keyed_load_string_length(), 1); |
| 3366 | 3356 |
| 3367 // Check that the name has not changed. | 3357 // Check that the name has not changed. |
| 3368 __ cmp(eax, Immediate(Handle<String>(name))); | 3358 __ cmp(eax, Immediate(name)); |
| 3369 __ j(not_equal, &miss); | 3359 __ j(not_equal, &miss); |
| 3370 | 3360 |
| 3371 GenerateLoadStringLength(masm(), edx, ecx, ebx, &miss, true); | 3361 GenerateLoadStringLength(masm(), edx, ecx, ebx, &miss, true); |
| 3372 __ bind(&miss); | 3362 __ bind(&miss); |
| 3373 __ DecrementCounter(counters->keyed_load_string_length(), 1); | 3363 __ DecrementCounter(counters->keyed_load_string_length(), 1); |
| 3374 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3364 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 3375 | 3365 |
| 3376 // Return the generated code. | 3366 // Return the generated code. |
| 3377 return GetCode(CALLBACKS, name); | 3367 return GetCode(CALLBACKS, name); |
| 3378 } | 3368 } |
| 3379 | 3369 |
| 3380 | 3370 |
| 3381 MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { | 3371 Handle<Code> KeyedLoadStubCompiler::CompileLoadFunctionPrototype( |
| 3372 Handle<String> name) { |
| 3382 // ----------- S t a t e ------------- | 3373 // ----------- S t a t e ------------- |
| 3383 // -- eax : key | 3374 // -- eax : key |
| 3384 // -- edx : receiver | 3375 // -- edx : receiver |
| 3385 // -- esp[0] : return address | 3376 // -- esp[0] : return address |
| 3386 // ----------------------------------- | 3377 // ----------------------------------- |
| 3387 Label miss; | 3378 Label miss; |
| 3388 | 3379 |
| 3389 Counters* counters = isolate()->counters(); | 3380 Counters* counters = isolate()->counters(); |
| 3390 __ IncrementCounter(counters->keyed_load_function_prototype(), 1); | 3381 __ IncrementCounter(counters->keyed_load_function_prototype(), 1); |
| 3391 | 3382 |
| 3392 // Check that the name has not changed. | 3383 // Check that the name has not changed. |
| 3393 __ cmp(eax, Immediate(Handle<String>(name))); | 3384 __ cmp(eax, Immediate(name)); |
| 3394 __ j(not_equal, &miss); | 3385 __ j(not_equal, &miss); |
| 3395 | 3386 |
| 3396 GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss); | 3387 GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss); |
| 3397 __ bind(&miss); | 3388 __ bind(&miss); |
| 3398 __ DecrementCounter(counters->keyed_load_function_prototype(), 1); | 3389 __ DecrementCounter(counters->keyed_load_function_prototype(), 1); |
| 3399 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3390 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 3400 | 3391 |
| 3401 // Return the generated code. | 3392 // Return the generated code. |
| 3402 return GetCode(CALLBACKS, name); | 3393 return GetCode(CALLBACKS, name); |
| 3403 } | 3394 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3414 MaybeObject* maybe_stub = KeyedLoadElementStub(elements_kind).TryGetCode(); | 3405 MaybeObject* maybe_stub = KeyedLoadElementStub(elements_kind).TryGetCode(); |
| 3415 if (!maybe_stub->To(&stub)) return maybe_stub; | 3406 if (!maybe_stub->To(&stub)) return maybe_stub; |
| 3416 __ DispatchMap(edx, | 3407 __ DispatchMap(edx, |
| 3417 Handle<Map>(receiver_map), | 3408 Handle<Map>(receiver_map), |
| 3418 Handle<Code>(stub), | 3409 Handle<Code>(stub), |
| 3419 DO_SMI_CHECK); | 3410 DO_SMI_CHECK); |
| 3420 | 3411 |
| 3421 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3412 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 3422 | 3413 |
| 3423 // Return the generated code. | 3414 // Return the generated code. |
| 3424 return GetCode(NORMAL, NULL); | 3415 return TryGetCode(NORMAL, NULL); |
| 3425 } | 3416 } |
| 3426 | 3417 |
| 3427 | 3418 |
| 3428 MaybeObject* KeyedLoadStubCompiler::CompileLoadPolymorphic( | 3419 MaybeObject* KeyedLoadStubCompiler::CompileLoadPolymorphic( |
| 3429 MapList* receiver_maps, | 3420 MapList* receiver_maps, |
| 3430 CodeList* handler_ics) { | 3421 CodeList* handler_ics) { |
| 3431 // ----------- S t a t e ------------- | 3422 // ----------- S t a t e ------------- |
| 3432 // -- eax : key | 3423 // -- eax : key |
| 3433 // -- edx : receiver | 3424 // -- edx : receiver |
| 3434 // -- esp[0] : return address | 3425 // -- esp[0] : return address |
| 3435 // ----------------------------------- | 3426 // ----------------------------------- |
| 3436 Label miss; | 3427 Label miss; |
| 3437 __ JumpIfSmi(edx, &miss); | 3428 __ JumpIfSmi(edx, &miss); |
| 3438 | 3429 |
| 3439 Register map_reg = ebx; | 3430 Register map_reg = ebx; |
| 3440 __ mov(map_reg, FieldOperand(edx, HeapObject::kMapOffset)); | 3431 __ mov(map_reg, FieldOperand(edx, HeapObject::kMapOffset)); |
| 3441 int receiver_count = receiver_maps->length(); | 3432 int receiver_count = receiver_maps->length(); |
| 3442 for (int current = 0; current < receiver_count; ++current) { | 3433 for (int current = 0; current < receiver_count; ++current) { |
| 3443 Handle<Map> map(receiver_maps->at(current)); | 3434 Handle<Map> map(receiver_maps->at(current)); |
| 3444 __ cmp(map_reg, map); | 3435 __ cmp(map_reg, map); |
| 3445 __ j(equal, Handle<Code>(handler_ics->at(current))); | 3436 __ j(equal, Handle<Code>(handler_ics->at(current))); |
| 3446 } | 3437 } |
| 3447 | 3438 |
| 3448 __ bind(&miss); | 3439 __ bind(&miss); |
| 3449 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3440 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 3450 | 3441 |
| 3451 // Return the generated code. | 3442 // Return the generated code. |
| 3452 return GetCode(NORMAL, NULL, MEGAMORPHIC); | 3443 return TryGetCode(NORMAL, NULL, MEGAMORPHIC); |
| 3453 } | 3444 } |
| 3454 | 3445 |
| 3455 | 3446 |
| 3456 // Specialized stub for constructing objects from functions which only have only | 3447 // Specialized stub for constructing objects from functions which only have only |
| 3457 // simple assignments of the form this.x = ...; in their body. | 3448 // simple assignments of the form this.x = ...; in their body. |
| 3458 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { | 3449 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { |
| 3459 // ----------- S t a t e ------------- | 3450 // ----------- S t a t e ------------- |
| 3460 // -- eax : argc | 3451 // -- eax : argc |
| 3461 // -- edi : constructor | 3452 // -- edi : constructor |
| 3462 // -- esp[0] : return address | 3453 // -- esp[0] : return address |
| (...skipping 768 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4231 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); | 4222 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); |
| 4232 __ jmp(ic_miss, RelocInfo::CODE_TARGET); | 4223 __ jmp(ic_miss, RelocInfo::CODE_TARGET); |
| 4233 } | 4224 } |
| 4234 | 4225 |
| 4235 | 4226 |
| 4236 #undef __ | 4227 #undef __ |
| 4237 | 4228 |
| 4238 } } // namespace v8::internal | 4229 } } // namespace v8::internal |
| 4239 | 4230 |
| 4240 #endif // V8_TARGET_ARCH_IA32 | 4231 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |