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 |