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 3112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3123 &miss); | 3123 &miss); |
3124 | 3124 |
3125 __ bind(&miss); | 3125 __ bind(&miss); |
3126 GenerateLoadMiss(masm(), Code::LOAD_IC); | 3126 GenerateLoadMiss(masm(), Code::LOAD_IC); |
3127 | 3127 |
3128 // Return the generated code. | 3128 // Return the generated code. |
3129 return TryGetCode(INTERCEPTOR, name); | 3129 return TryGetCode(INTERCEPTOR, name); |
3130 } | 3130 } |
3131 | 3131 |
3132 | 3132 |
3133 MaybeObject* LoadStubCompiler::CompileLoadGlobal(JSObject* object, | 3133 Handle<Code> LoadStubCompiler::CompileLoadGlobal( |
3134 GlobalObject* holder, | 3134 Handle<JSObject> object, |
3135 JSGlobalPropertyCell* cell, | 3135 Handle<GlobalObject> holder, |
3136 String* name, | 3136 Handle<JSGlobalPropertyCell> cell, |
3137 bool is_dont_delete) { | 3137 Handle<String> name, |
3138 bool is_dont_delete) { | |
3138 // ----------- S t a t e ------------- | 3139 // ----------- S t a t e ------------- |
3139 // -- eax : receiver | 3140 // -- eax : receiver |
3140 // -- ecx : name | 3141 // -- ecx : name |
3141 // -- esp[0] : return address | 3142 // -- esp[0] : return address |
3142 // ----------------------------------- | 3143 // ----------------------------------- |
3143 Label miss; | 3144 Label miss; |
3144 | 3145 |
3145 // 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 |
3146 // object which can only happen for contextual loads. In this case, | 3147 // object which can only happen for contextual loads. In this case, |
3147 // the receiver cannot be a smi. | 3148 // the receiver cannot be a smi. |
3148 if (object != holder) { | 3149 if (!object.is_identical_to(holder)) { |
3149 __ JumpIfSmi(eax, &miss); | 3150 __ JumpIfSmi(eax, &miss); |
3150 } | 3151 } |
3151 | 3152 |
3152 // Check that the maps haven't changed. | 3153 // Check that the maps haven't changed. |
3153 CheckPrototypes(object, eax, holder, ebx, edx, edi, name, &miss); | 3154 CheckPrototypes(object, eax, holder, ebx, edx, edi, name, &miss); |
3154 | 3155 |
3155 // Get the value from the cell. | 3156 // Get the value from the cell. |
3156 if (Serializer::enabled()) { | 3157 if (Serializer::enabled()) { |
3157 __ mov(ebx, Immediate(Handle<JSGlobalPropertyCell>(cell))); | 3158 __ mov(ebx, Immediate(cell)); |
3158 __ mov(ebx, FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset)); | 3159 __ mov(ebx, FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset)); |
3159 } else { | 3160 } else { |
3160 __ mov(ebx, Operand::Cell(Handle<JSGlobalPropertyCell>(cell))); | 3161 __ mov(ebx, Operand::Cell(cell)); |
3161 } | 3162 } |
3162 | 3163 |
3163 // Check for deleted property if property can actually be deleted. | 3164 // Check for deleted property if property can actually be deleted. |
3164 if (!is_dont_delete) { | 3165 if (!is_dont_delete) { |
3165 __ cmp(ebx, factory()->the_hole_value()); | 3166 __ cmp(ebx, factory()->the_hole_value()); |
3166 __ j(equal, &miss); | 3167 __ j(equal, &miss); |
3167 } else if (FLAG_debug_code) { | 3168 } else if (FLAG_debug_code) { |
3168 __ cmp(ebx, factory()->the_hole_value()); | 3169 __ cmp(ebx, factory()->the_hole_value()); |
3169 __ Check(not_equal, "DontDelete cells can't contain the hole"); | 3170 __ Check(not_equal, "DontDelete cells can't contain the hole"); |
3170 } | 3171 } |
3171 | 3172 |
3172 Counters* counters = isolate()->counters(); | 3173 Counters* counters = isolate()->counters(); |
3173 __ IncrementCounter(counters->named_load_global_stub(), 1); | 3174 __ IncrementCounter(counters->named_load_global_stub(), 1); |
3174 __ mov(eax, ebx); | 3175 __ mov(eax, ebx); |
3175 __ ret(0); | 3176 __ ret(0); |
3176 | 3177 |
3177 __ bind(&miss); | 3178 __ bind(&miss); |
3178 __ IncrementCounter(counters->named_load_global_stub_miss(), 1); | 3179 __ IncrementCounter(counters->named_load_global_stub_miss(), 1); |
3179 GenerateLoadMiss(masm(), Code::LOAD_IC); | 3180 GenerateLoadMiss(masm(), Code::LOAD_IC); |
3180 | 3181 |
3181 // Return the generated code. | 3182 // Return the generated code. |
3182 return TryGetCode(NORMAL, name); | 3183 return GetCode(NORMAL, name); |
3183 } | 3184 } |
3184 | 3185 |
3185 | 3186 |
3186 Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name, | 3187 Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name, |
3187 Handle<JSObject> receiver, | 3188 Handle<JSObject> receiver, |
3188 Handle<JSObject> holder, | 3189 Handle<JSObject> holder, |
3189 int index) { | 3190 int index) { |
3190 // ----------- S t a t e ------------- | 3191 // ----------- S t a t e ------------- |
3191 // -- eax : key | 3192 // -- eax : key |
3192 // -- edx : receiver | 3193 // -- edx : receiver |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3387 GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss); | 3388 GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss); |
3388 __ bind(&miss); | 3389 __ bind(&miss); |
3389 __ DecrementCounter(counters->keyed_load_function_prototype(), 1); | 3390 __ DecrementCounter(counters->keyed_load_function_prototype(), 1); |
3390 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3391 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3391 | 3392 |
3392 // Return the generated code. | 3393 // Return the generated code. |
3393 return GetCode(CALLBACKS, name); | 3394 return GetCode(CALLBACKS, name); |
3394 } | 3395 } |
3395 | 3396 |
3396 | 3397 |
3397 MaybeObject* KeyedLoadStubCompiler::CompileLoadElement(Map* receiver_map) { | 3398 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement( |
3399 Handle<Map> receiver_map) { | |
3398 // ----------- S t a t e ------------- | 3400 // ----------- S t a t e ------------- |
3399 // -- eax : key | 3401 // -- eax : key |
3400 // -- edx : receiver | 3402 // -- edx : receiver |
3401 // -- esp[0] : return address | 3403 // -- esp[0] : return address |
3402 // ----------------------------------- | 3404 // ----------------------------------- |
3403 Code* stub; | 3405 |
3404 ElementsKind elements_kind = receiver_map->elements_kind(); | 3406 ElementsKind elements_kind = receiver_map->elements_kind(); |
3405 MaybeObject* maybe_stub = KeyedLoadElementStub(elements_kind).TryGetCode(); | 3407 Handle<Code> stub = KeyedLoadElementStub(elements_kind).GetCode(); |
3406 if (!maybe_stub->To(&stub)) return maybe_stub; | 3408 |
3407 __ DispatchMap(edx, | 3409 __ DispatchMap(edx, |
Kevin Millikin (Chromium)
2011/10/26 08:43:41
Again, fits on one line.
| |
3408 Handle<Map>(receiver_map), | 3410 receiver_map, |
3409 Handle<Code>(stub), | 3411 stub, |
3410 DO_SMI_CHECK); | 3412 DO_SMI_CHECK); |
3411 | 3413 |
3412 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3414 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3413 | 3415 |
3414 // Return the generated code. | 3416 // Return the generated code. |
3415 return TryGetCode(NORMAL, NULL); | 3417 return GetCode(NORMAL, factory()->empty_string()); |
3416 } | 3418 } |
3417 | 3419 |
3418 | 3420 |
3419 MaybeObject* KeyedLoadStubCompiler::CompileLoadPolymorphic( | 3421 Handle<Code> KeyedLoadStubCompiler::CompileLoadPolymorphic( |
3420 MapList* receiver_maps, | 3422 MapHandleList* receiver_maps, |
3421 CodeList* handler_ics) { | 3423 CodeHandleList* handler_ics) { |
3422 // ----------- S t a t e ------------- | 3424 // ----------- S t a t e ------------- |
3423 // -- eax : key | 3425 // -- eax : key |
3424 // -- edx : receiver | 3426 // -- edx : receiver |
3425 // -- esp[0] : return address | 3427 // -- esp[0] : return address |
3426 // ----------------------------------- | 3428 // ----------------------------------- |
3427 Label miss; | 3429 Label miss; |
3428 __ JumpIfSmi(edx, &miss); | 3430 __ JumpIfSmi(edx, &miss); |
3429 | 3431 |
3430 Register map_reg = ebx; | 3432 Register map_reg = ebx; |
3431 __ mov(map_reg, FieldOperand(edx, HeapObject::kMapOffset)); | 3433 __ mov(map_reg, FieldOperand(edx, HeapObject::kMapOffset)); |
3432 int receiver_count = receiver_maps->length(); | 3434 int receiver_count = receiver_maps->length(); |
3433 for (int current = 0; current < receiver_count; ++current) { | 3435 for (int current = 0; current < receiver_count; ++current) { |
3434 Handle<Map> map(receiver_maps->at(current)); | 3436 __ cmp(map_reg, receiver_maps->at(current)); |
3435 __ cmp(map_reg, map); | 3437 __ j(equal, handler_ics->at(current)); |
3436 __ j(equal, Handle<Code>(handler_ics->at(current))); | |
3437 } | 3438 } |
3438 | 3439 |
3439 __ bind(&miss); | 3440 __ bind(&miss); |
3440 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3441 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3441 | 3442 |
3442 // Return the generated code. | 3443 // Return the generated code. |
3443 return TryGetCode(NORMAL, NULL, MEGAMORPHIC); | 3444 return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC); |
3444 } | 3445 } |
3445 | 3446 |
3446 | 3447 |
3447 // Specialized stub for constructing objects from functions which only have only | 3448 // Specialized stub for constructing objects from functions which only have only |
3448 // simple assignments of the form this.x = ...; in their body. | 3449 // simple assignments of the form this.x = ...; in their body. |
3449 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { | 3450 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { |
3450 // ----------- S t a t e ------------- | 3451 // ----------- S t a t e ------------- |
3451 // -- eax : argc | 3452 // -- eax : argc |
3452 // -- edi : constructor | 3453 // -- edi : constructor |
3453 // -- esp[0] : return address | 3454 // -- esp[0] : return address |
(...skipping 768 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4222 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); | 4223 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); |
4223 __ jmp(ic_miss, RelocInfo::CODE_TARGET); | 4224 __ jmp(ic_miss, RelocInfo::CODE_TARGET); |
4224 } | 4225 } |
4225 | 4226 |
4226 | 4227 |
4227 #undef __ | 4228 #undef __ |
4228 | 4229 |
4229 } } // namespace v8::internal | 4230 } } // namespace v8::internal |
4230 | 4231 |
4231 #endif // V8_TARGET_ARCH_IA32 | 4232 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |