OLD | NEW |
---|---|
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 3217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3228 __ mov(tmp.reg(), ContextOperand(tmp.reg(), Context::CLOSURE_INDEX)); | 3228 __ mov(tmp.reg(), ContextOperand(tmp.reg(), Context::CLOSURE_INDEX)); |
3229 __ mov(tmp.reg(), FieldOperand(tmp.reg(), JSFunction::kContextOffset)); | 3229 __ mov(tmp.reg(), FieldOperand(tmp.reg(), JSFunction::kContextOffset)); |
3230 __ jmp(&next); | 3230 __ jmp(&next); |
3231 __ bind(&fast); | 3231 __ bind(&fast); |
3232 } | 3232 } |
3233 context.Unuse(); | 3233 context.Unuse(); |
3234 tmp.Unuse(); | 3234 tmp.Unuse(); |
3235 | 3235 |
3236 // All extension objects were empty and it is safe to use a global | 3236 // All extension objects were empty and it is safe to use a global |
3237 // load IC call. | 3237 // load IC call. |
3238 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | |
3239 // Load the global object. | |
3240 LoadGlobal(); | 3238 LoadGlobal(); |
3241 // Setup the name register. All non-reserved registers are available. | 3239 frame_->Push(slot->var()->name()); |
3242 Result name = allocator_->Allocate(ecx); | 3240 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) |
3243 ASSERT(name.is_valid()); | 3241 ? RelocInfo::CODE_TARGET |
3244 __ mov(name.reg(), slot->var()->name()); | 3242 : RelocInfo::CODE_TARGET_CONTEXT; |
3245 RelocInfo::Mode rmode = (typeof_state == INSIDE_TYPEOF) | 3243 Result answer = frame_->CallLoadIC(mode); |
3246 ? RelocInfo::CODE_TARGET | |
3247 : RelocInfo::CODE_TARGET_CONTEXT; | |
3248 Result answer = frame_->CallCodeObject(ic, rmode, &name, 0); | |
3249 | 3244 |
3250 // Discard the global object. The result is in answer. | 3245 // Discard the global object. The result is in answer. |
3251 frame_->Drop(); | 3246 frame_->Drop(); |
3252 return answer; | 3247 return answer; |
3253 } | 3248 } |
3254 | 3249 |
3255 | 3250 |
3256 void CodeGenerator::StoreToSlot(Slot* slot, InitState init_state) { | 3251 void CodeGenerator::StoreToSlot(Slot* slot, InitState init_state) { |
3257 if (slot->type() == Slot::LOOKUP) { | 3252 if (slot->type() == Slot::LOOKUP) { |
3258 ASSERT(slot->var()->is_dynamic()); | 3253 ASSERT(slot->var()->is_dynamic()); |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3545 for (int i = 0; i < node->properties()->length(); i++) { | 3540 for (int i = 0; i < node->properties()->length(); i++) { |
3546 ObjectLiteral::Property* property = node->properties()->at(i); | 3541 ObjectLiteral::Property* property = node->properties()->at(i); |
3547 switch (property->kind()) { | 3542 switch (property->kind()) { |
3548 case ObjectLiteral::Property::CONSTANT: | 3543 case ObjectLiteral::Property::CONSTANT: |
3549 break; | 3544 break; |
3550 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 3545 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
3551 if (CompileTimeValue::IsCompileTimeValue(property->value())) break; | 3546 if (CompileTimeValue::IsCompileTimeValue(property->value())) break; |
3552 // else fall through. | 3547 // else fall through. |
3553 case ObjectLiteral::Property::COMPUTED: { | 3548 case ObjectLiteral::Property::COMPUTED: { |
3554 Handle<Object> key(property->key()->handle()); | 3549 Handle<Object> key(property->key()->handle()); |
3555 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | |
3556 if (key->IsSymbol()) { | 3550 if (key->IsSymbol()) { |
3557 // Duplicate the object as the IC receiver. | 3551 // Duplicate the object as the IC receiver. |
3558 frame_->Dup(); | 3552 frame_->Dup(); |
3559 Load(property->value()); | 3553 Load(property->value()); |
3560 Result value = frame_->Pop(); | 3554 frame_->Push(key); |
3561 value.ToRegister(eax); | 3555 Result ignored = frame_->CallStoreIC(); |
3562 | |
3563 Result name = allocator_->Allocate(ecx); | |
3564 ASSERT(name.is_valid()); | |
3565 __ Set(name.reg(), Immediate(key)); | |
3566 Result ignored = | |
3567 frame_->CallCodeObject(ic, RelocInfo::CODE_TARGET, | |
3568 &value, &name, 0); | |
3569 // Drop the duplicated receiver and ignore the result. | 3556 // Drop the duplicated receiver and ignore the result. |
3570 frame_->Drop(); | 3557 frame_->Drop(); |
3571 break; | 3558 break; |
3572 } | 3559 } |
3573 // Fall through | 3560 // Fall through |
3574 } | 3561 } |
3575 case ObjectLiteral::Property::PROTOTYPE: { | 3562 case ObjectLiteral::Property::PROTOTYPE: { |
3576 // Duplicate the object as an argument to the runtime call. | 3563 // Duplicate the object as an argument to the runtime call. |
3577 frame_->Dup(); | 3564 frame_->Dup(); |
3578 Load(property->key()); | 3565 Load(property->key()); |
(...skipping 1601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5180 Label* patch_site() { return &patch_site_; } | 5167 Label* patch_site() { return &patch_site_; } |
5181 | 5168 |
5182 private: | 5169 private: |
5183 Label patch_site_; | 5170 Label patch_site_; |
5184 bool is_global_; | 5171 bool is_global_; |
5185 }; | 5172 }; |
5186 | 5173 |
5187 | 5174 |
5188 void DeferredReferenceGetKeyedValue::Generate() { | 5175 void DeferredReferenceGetKeyedValue::Generate() { |
5189 CodeGenerator* cgen = generator(); | 5176 CodeGenerator* cgen = generator(); |
5190 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | |
5191 Result receiver(cgen); | 5177 Result receiver(cgen); |
5192 Result key(cgen); | 5178 Result key(cgen); |
5193 enter()->Bind(&receiver, &key); | 5179 enter()->Bind(&receiver, &key); |
5194 cgen->frame()->Push(&receiver); // First IC argument. | 5180 cgen->frame()->Push(&receiver); // First IC argument. |
5195 cgen->frame()->Push(&key); // Second IC argument. | 5181 cgen->frame()->Push(&key); // Second IC argument. |
5196 | 5182 |
5197 // Calculate the delta from the IC call instruction to the map check | 5183 // Calculate the delta from the IC call instruction to the map check |
5198 // cmp instruction in the inlined version. This delta is stored in | 5184 // cmp instruction in the inlined version. This delta is stored in |
5199 // a test(eax, delta) instruction after the call so that we can find | 5185 // a test(eax, delta) instruction after the call so that we can find |
5200 // it in the IC initialization code and patch the cmp instruction. | 5186 // it in the IC initialization code and patch the cmp instruction. |
5201 // This means that we cannot allow test instructions after calls to | 5187 // This means that we cannot allow test instructions after calls to |
5202 // KeyedLoadIC stubs in other places. | 5188 // KeyedLoadIC stubs in other places. |
5203 Result value(cgen); | 5189 RelocInfo::Mode mode = is_global_ |
5204 if (is_global_) { | 5190 ? RelocInfo::CODE_TARGET_CONTEXT |
Kasper Lund
2009/03/25 13:25:34
4 space indent here?
| |
5205 value = cgen->frame()->CallCodeObject(ic, | 5191 : RelocInfo::CODE_TARGET; |
5206 RelocInfo::CODE_TARGET_CONTEXT, | 5192 Result value = cgen->frame()->CallKeyedLoadIC(mode); |
5207 0); | |
5208 } else { | |
5209 value = cgen->frame()->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0); | |
5210 } | |
5211 // The result needs to be specifically the eax register because the | 5193 // The result needs to be specifically the eax register because the |
5212 // offset to the patch site will be expected in a test eax | 5194 // offset to the patch site will be expected in a test eax |
5213 // instruction. | 5195 // instruction. |
5214 ASSERT(value.is_register() && value.reg().is(eax)); | 5196 ASSERT(value.is_register() && value.reg().is(eax)); |
5215 // The delta from the start of the map-compare instruction to the | 5197 // The delta from the start of the map-compare instruction to the |
5216 // test eax instruction. | 5198 // test eax instruction. |
5217 int delta_to_patch_site = __ SizeOfCodeGeneratedSince(patch_site()); | 5199 int delta_to_patch_site = __ SizeOfCodeGeneratedSince(patch_site()); |
5218 __ test(value.reg(), Immediate(-delta_to_patch_site)); | 5200 __ test(value.reg(), Immediate(-delta_to_patch_site)); |
5219 __ IncrementCounter(&Counters::keyed_load_inline_miss, 1); | 5201 __ IncrementCounter(&Counters::keyed_load_inline_miss, 1); |
5220 | 5202 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5262 break; | 5244 break; |
5263 } | 5245 } |
5264 | 5246 |
5265 case NAMED: { | 5247 case NAMED: { |
5266 // TODO(1241834): Make sure that it is safe to ignore the | 5248 // TODO(1241834): Make sure that it is safe to ignore the |
5267 // distinction between expressions in a typeof and not in a | 5249 // distinction between expressions in a typeof and not in a |
5268 // typeof. If there is a chance that reference errors can be | 5250 // typeof. If there is a chance that reference errors can be |
5269 // thrown below, we must distinguish between the two kinds of | 5251 // thrown below, we must distinguish between the two kinds of |
5270 // loads (typeof expression loads must not throw a reference | 5252 // loads (typeof expression loads must not throw a reference |
5271 // error). | 5253 // error). |
5272 VirtualFrame* frame = cgen_->frame(); | |
5273 Comment cmnt(masm, "[ Load from named Property"); | 5254 Comment cmnt(masm, "[ Load from named Property"); |
5274 Handle<String> name(GetName()); | 5255 cgen_->frame()->Push(GetName()); |
5256 | |
5275 Variable* var = expression_->AsVariableProxy()->AsVariable(); | 5257 Variable* var = expression_->AsVariableProxy()->AsVariable(); |
5276 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | |
5277 // Setup the name register. | |
5278 Result name_reg = cgen_->allocator()->Allocate(ecx); | |
5279 ASSERT(name_reg.is_valid()); | |
5280 __ mov(name_reg.reg(), name); | |
5281 ASSERT(var == NULL || var->is_global()); | 5258 ASSERT(var == NULL || var->is_global()); |
5282 RelocInfo::Mode rmode = (var == NULL) | 5259 RelocInfo::Mode mode = (var == NULL) |
5283 ? RelocInfo::CODE_TARGET | 5260 ? RelocInfo::CODE_TARGET |
5284 : RelocInfo::CODE_TARGET_CONTEXT; | 5261 : RelocInfo::CODE_TARGET_CONTEXT; |
5285 Result answer = frame->CallCodeObject(ic, rmode, &name_reg, 0); | 5262 Result answer = cgen_->frame()->CallLoadIC(mode); |
5286 frame->Push(&answer); | 5263 cgen_->frame()->Push(&answer); |
5287 break; | 5264 break; |
5288 } | 5265 } |
5289 | 5266 |
5290 case KEYED: { | 5267 case KEYED: { |
5291 // TODO(1241834): Make sure that this it is safe to ignore the | 5268 // TODO(1241834): Make sure that this it is safe to ignore the |
5292 // distinction between expressions in a typeof and not in a typeof. | 5269 // distinction between expressions in a typeof and not in a typeof. |
5293 Comment cmnt(masm, "[ Load from keyed Property"); | 5270 Comment cmnt(masm, "[ Load from keyed Property"); |
5294 Variable* var = expression_->AsVariableProxy()->AsVariable(); | 5271 Variable* var = expression_->AsVariableProxy()->AsVariable(); |
5295 bool is_global = var != NULL; | 5272 bool is_global = var != NULL; |
5296 ASSERT(!is_global || var->is_global()); | 5273 ASSERT(!is_global || var->is_global()); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5366 __ IncrementCounter(&Counters::keyed_load_inline, 1); | 5343 __ IncrementCounter(&Counters::keyed_load_inline, 1); |
5367 | 5344 |
5368 // Restore the receiver and key to the frame and push the | 5345 // Restore the receiver and key to the frame and push the |
5369 // result on top of it. | 5346 // result on top of it. |
5370 deferred->BindExit(&receiver, &key, &value); | 5347 deferred->BindExit(&receiver, &key, &value); |
5371 cgen_->frame()->Push(&receiver); | 5348 cgen_->frame()->Push(&receiver); |
5372 cgen_->frame()->Push(&key); | 5349 cgen_->frame()->Push(&key); |
5373 cgen_->frame()->Push(&value); | 5350 cgen_->frame()->Push(&value); |
5374 | 5351 |
5375 } else { | 5352 } else { |
5376 VirtualFrame* frame = cgen_->frame(); | |
5377 Comment cmnt(masm, "[ Load from keyed Property"); | 5353 Comment cmnt(masm, "[ Load from keyed Property"); |
5378 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 5354 RelocInfo::Mode mode = is_global |
5379 RelocInfo::Mode rmode = is_global | 5355 ? RelocInfo::CODE_TARGET_CONTEXT |
5380 ? RelocInfo::CODE_TARGET_CONTEXT | 5356 : RelocInfo::CODE_TARGET; |
5381 : RelocInfo::CODE_TARGET; | 5357 Result answer = cgen_->frame()->CallKeyedLoadIC(mode); |
5382 Result answer = frame->CallCodeObject(ic, rmode, 0); | |
5383 // Make sure that we do not have a test instruction after the | 5358 // Make sure that we do not have a test instruction after the |
5384 // call. A test instruction after the call is used to | 5359 // call. A test instruction after the call is used to |
5385 // indicate that we have generated an inline version of the | 5360 // indicate that we have generated an inline version of the |
5386 // keyed load. The explicit nop instruction is here because | 5361 // keyed load. The explicit nop instruction is here because |
5387 // the push that follows might be peep-hole optimized away. | 5362 // the push that follows might be peep-hole optimized away. |
5388 __ nop(); | 5363 __ nop(); |
5389 frame->Push(&answer); | 5364 cgen_->frame()->Push(&answer); |
5390 } | 5365 } |
5391 break; | 5366 break; |
5392 } | 5367 } |
5393 | 5368 |
5394 default: | 5369 default: |
5395 UNREACHABLE(); | 5370 UNREACHABLE(); |
5396 } | 5371 } |
5397 } | 5372 } |
5398 | 5373 |
5399 | 5374 |
(...skipping 23 matching lines...) Expand all Loading... | |
5423 } else { | 5398 } else { |
5424 ASSERT(slot->type() == Slot::LOCAL); | 5399 ASSERT(slot->type() == Slot::LOCAL); |
5425 cgen_->frame()->TakeLocalAt(slot->index()); | 5400 cgen_->frame()->TakeLocalAt(slot->index()); |
5426 } | 5401 } |
5427 } | 5402 } |
5428 | 5403 |
5429 | 5404 |
5430 void Reference::SetValue(InitState init_state) { | 5405 void Reference::SetValue(InitState init_state) { |
5431 ASSERT(cgen_->HasValidEntryRegisters()); | 5406 ASSERT(cgen_->HasValidEntryRegisters()); |
5432 ASSERT(!is_illegal()); | 5407 ASSERT(!is_illegal()); |
5433 MacroAssembler* masm = cgen_->masm(); | |
5434 VirtualFrame* frame = cgen_->frame(); | |
5435 switch (type_) { | 5408 switch (type_) { |
5436 case SLOT: { | 5409 case SLOT: { |
5437 Comment cmnt(masm, "[ Store to Slot"); | 5410 Comment cmnt(cgen_->masm(), "[ Store to Slot"); |
5438 Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot(); | 5411 Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot(); |
5439 ASSERT(slot != NULL); | 5412 ASSERT(slot != NULL); |
5440 cgen_->StoreToSlot(slot, init_state); | 5413 cgen_->StoreToSlot(slot, init_state); |
5441 break; | 5414 break; |
5442 } | 5415 } |
5443 | 5416 |
5444 case NAMED: { | 5417 case NAMED: { |
5445 Comment cmnt(masm, "[ Store to named Property"); | 5418 Comment cmnt(cgen_->masm(), "[ Store to named Property"); |
5446 // Call the appropriate IC code. | 5419 cgen_->frame()->Push(GetName()); |
5447 Handle<String> name(GetName()); | 5420 Result answer = cgen_->frame()->CallStoreIC(); |
5448 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 5421 cgen_->frame()->Push(&answer); |
5449 // TODO(1222589): Make the IC grab the values from the stack. | |
5450 Result argument = frame->Pop(); | |
5451 argument.ToRegister(eax); | |
5452 ASSERT(argument.is_valid()); | |
5453 Result property_name = cgen_->allocator()->Allocate(ecx); | |
5454 ASSERT(property_name.is_valid()); | |
5455 // Setup the name register. | |
5456 __ mov(property_name.reg(), name); | |
5457 Result answer = frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, | |
5458 &argument, &property_name, 0); | |
5459 frame->Push(&answer); | |
5460 break; | 5422 break; |
5461 } | 5423 } |
5462 | 5424 |
5463 case KEYED: { | 5425 case KEYED: { |
5464 Comment cmnt(masm, "[ Store to keyed Property"); | 5426 Comment cmnt(cgen_->masm(), "[ Store to keyed Property"); |
5465 // Call IC code. | 5427 Result answer = cgen_->frame()->CallKeyedStoreIC(); |
5466 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 5428 cgen_->frame()->Push(&answer); |
5467 // TODO(1222589): Make the IC grab the values from the stack. | |
5468 Result arg = frame->Pop(); | |
5469 arg.ToRegister(eax); | |
5470 ASSERT(arg.is_valid()); | |
5471 Result answer = frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, | |
5472 &arg, 0); | |
5473 frame->Push(&answer); | |
5474 break; | 5429 break; |
5475 } | 5430 } |
5476 | 5431 |
5477 default: | 5432 default: |
5478 UNREACHABLE(); | 5433 UNREACHABLE(); |
5479 } | 5434 } |
5480 } | 5435 } |
5481 | 5436 |
5482 | 5437 |
5483 // NOTE: The stub does not handle the inlined cases (Smis, Booleans, undefined). | 5438 // NOTE: The stub does not handle the inlined cases (Smis, Booleans, undefined). |
(...skipping 1504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6988 | 6943 |
6989 // Slow-case: Go through the JavaScript implementation. | 6944 // Slow-case: Go through the JavaScript implementation. |
6990 __ bind(&slow); | 6945 __ bind(&slow); |
6991 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); | 6946 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); |
6992 } | 6947 } |
6993 | 6948 |
6994 | 6949 |
6995 #undef __ | 6950 #undef __ |
6996 | 6951 |
6997 } } // namespace v8::internal | 6952 } } // namespace v8::internal |
OLD | NEW |