OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 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 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 Comment cmnt(masm_, "[ VariableProxy"); | 198 Comment cmnt(masm_, "[ VariableProxy"); |
199 Expression* rewrite = expr->var()->rewrite(); | 199 Expression* rewrite = expr->var()->rewrite(); |
200 if (rewrite == NULL) { | 200 if (rewrite == NULL) { |
201 Comment cmnt(masm_, "Global variable"); | 201 Comment cmnt(masm_, "Global variable"); |
202 // Use inline caching. Variable name is passed in ecx and the global | 202 // Use inline caching. Variable name is passed in ecx and the global |
203 // object on the stack. | 203 // object on the stack. |
204 __ push(CodeGenerator::GlobalObject()); | 204 __ push(CodeGenerator::GlobalObject()); |
205 __ mov(ecx, expr->name()); | 205 __ mov(ecx, expr->name()); |
206 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 206 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
207 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); | 207 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
| 208 // By emitting a nop we make sure that we do not have a test eax |
| 209 // instruction after the call it is treated specially by the LoadIC code |
| 210 // Remember that the assembler may choose to do peephole optimization |
| 211 // (eg, push/pop elimination). |
| 212 __ nop(); |
208 | 213 |
209 // A test eax instruction following the call is used by the IC to | |
210 // indicate that the inobject property case was inlined. Ensure there | |
211 // is no test eax instruction here. Remember that the assembler may | |
212 // choose to do peephole optimization (eg, push/pop elimination). | |
213 switch (expr->location().type()) { | 214 switch (expr->location().type()) { |
214 case Location::NOWHERE: | 215 case Location::NOWHERE: |
215 __ add(Operand(esp), Immediate(kPointerSize)); | 216 __ add(Operand(esp), Immediate(kPointerSize)); |
216 break; | 217 break; |
217 case Location::TEMP: | 218 case Location::TEMP: |
218 // Replace the global object with the result. | 219 // Replace the global object with the result. |
219 __ mov(Operand(esp, 0), eax); | 220 __ mov(Operand(esp, 0), eax); |
220 break; | 221 break; |
221 } | 222 } |
222 | 223 |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
485 // temporary on the stack. | 486 // temporary on the stack. |
486 __ mov(eax, Operand(esp, 0)); | 487 __ mov(eax, Operand(esp, 0)); |
487 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); | 488 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); |
488 break; | 489 break; |
489 } | 490 } |
490 } | 491 } |
491 } | 492 } |
492 } | 493 } |
493 | 494 |
494 | 495 |
| 496 void FastCodeGenerator::VisitProperty(Property* expr) { |
| 497 Comment cmnt(masm_, "[ Property"); |
| 498 Expression* key = expr->key(); |
| 499 uint32_t dummy; |
| 500 |
| 501 // Evaluate receiver. |
| 502 Visit(expr->obj()); |
| 503 |
| 504 if (key->AsLiteral() != NULL && key->AsLiteral()->handle()->IsSymbol() && |
| 505 !String::cast(*(key->AsLiteral()->handle()))->AsArrayIndex(&dummy)) { |
| 506 // Do a NAMED property load. |
| 507 // The IC expects the property name in ecx and the receiver on the stack. |
| 508 __ mov(ecx, Immediate(key->AsLiteral()->handle())); |
| 509 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
| 510 __ call(ic, RelocInfo::CODE_TARGET); |
| 511 // By emitting a nop we make sure that we do not have a test eax |
| 512 // instruction after the call it is treated specially by the LoadIC code. |
| 513 __ nop(); |
| 514 } else { |
| 515 // Do a KEYED property load. |
| 516 Visit(expr->key()); |
| 517 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
| 518 __ call(ic, RelocInfo::CODE_TARGET); |
| 519 // By emitting a nop we make sure that we do not have a "test eax,..." |
| 520 // instruction after the call it is treated specially by the LoadIC code. |
| 521 __ nop(); |
| 522 // Drop key left on the stack by IC. |
| 523 __ add(Operand(esp), Immediate(kPointerSize)); |
| 524 } |
| 525 switch (expr->location().type()) { |
| 526 case Location::TEMP: |
| 527 __ mov(Operand(esp, 0), eax); |
| 528 break; |
| 529 case Location::NOWHERE: |
| 530 __ add(Operand(esp), Immediate(kPointerSize)); |
| 531 break; |
| 532 } |
| 533 } |
| 534 |
| 535 |
495 void FastCodeGenerator::VisitCall(Call* expr) { | 536 void FastCodeGenerator::VisitCall(Call* expr) { |
496 Expression* fun = expr->expression(); | 537 Expression* fun = expr->expression(); |
497 ZoneList<Expression*>* args = expr->arguments(); | 538 ZoneList<Expression*>* args = expr->arguments(); |
498 Variable* var = fun->AsVariableProxy()->AsVariable(); | 539 Variable* var = fun->AsVariableProxy()->AsVariable(); |
499 ASSERT(var != NULL && !var->is_this() && var->is_global()); | 540 ASSERT(var != NULL && !var->is_this() && var->is_global()); |
500 ASSERT(!var->is_possibly_eval()); | 541 ASSERT(!var->is_possibly_eval()); |
501 | 542 |
502 __ push(Immediate(var->name())); | 543 __ push(Immediate(var->name())); |
503 // Push global object (receiver). | 544 // Push global object (receiver). |
504 __ push(CodeGenerator::GlobalObject()); | 545 __ push(CodeGenerator::GlobalObject()); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
617 } else { | 658 } else { |
618 Visit(right); | 659 Visit(right); |
619 Move(destination, right->location()); | 660 Move(destination, right->location()); |
620 } | 661 } |
621 | 662 |
622 __ bind(&done); | 663 __ bind(&done); |
623 } | 664 } |
624 | 665 |
625 | 666 |
626 } } // namespace v8::internal | 667 } } // namespace v8::internal |
OLD | NEW |