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 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
541 void FullCodeGenerator::DoTest(Label* if_true, | 541 void FullCodeGenerator::DoTest(Label* if_true, |
542 Label* if_false, | 542 Label* if_false, |
543 Label* fall_through) { | 543 Label* fall_through) { |
544 // Emit the inlined tests assumed by the stub. | 544 // Emit the inlined tests assumed by the stub. |
545 __ cmp(result_register(), Factory::undefined_value()); | 545 __ cmp(result_register(), Factory::undefined_value()); |
546 __ j(equal, if_false); | 546 __ j(equal, if_false); |
547 __ cmp(result_register(), Factory::true_value()); | 547 __ cmp(result_register(), Factory::true_value()); |
548 __ j(equal, if_true); | 548 __ j(equal, if_true); |
549 __ cmp(result_register(), Factory::false_value()); | 549 __ cmp(result_register(), Factory::false_value()); |
550 __ j(equal, if_false); | 550 __ j(equal, if_false); |
551 ASSERT_EQ(0, kSmiTag); | 551 STATIC_ASSERT(kSmiTag == 0); |
552 __ test(result_register(), Operand(result_register())); | 552 __ test(result_register(), Operand(result_register())); |
553 __ j(zero, if_false); | 553 __ j(zero, if_false); |
554 __ test(result_register(), Immediate(kSmiTagMask)); | 554 __ test(result_register(), Immediate(kSmiTagMask)); |
555 __ j(zero, if_true); | 555 __ j(zero, if_true); |
556 | 556 |
557 // Call the ToBoolean stub for all other cases. | 557 // Call the ToBoolean stub for all other cases. |
558 ToBooleanStub stub; | 558 ToBooleanStub stub; |
559 __ push(result_register()); | 559 __ push(result_register()); |
560 __ CallStub(&stub); | 560 __ CallStub(&stub); |
561 __ test(eax, Operand(eax)); | 561 __ test(eax, Operand(eax)); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
648 } | 648 } |
649 | 649 |
650 | 650 |
651 void FullCodeGenerator::EmitDeclaration(Variable* variable, | 651 void FullCodeGenerator::EmitDeclaration(Variable* variable, |
652 Variable::Mode mode, | 652 Variable::Mode mode, |
653 FunctionLiteral* function) { | 653 FunctionLiteral* function) { |
654 Comment cmnt(masm_, "[ Declaration"); | 654 Comment cmnt(masm_, "[ Declaration"); |
655 ASSERT(variable != NULL); // Must have been resolved. | 655 ASSERT(variable != NULL); // Must have been resolved. |
656 Slot* slot = variable->AsSlot(); | 656 Slot* slot = variable->AsSlot(); |
657 Property* prop = variable->AsProperty(); | 657 Property* prop = variable->AsProperty(); |
| 658 |
658 if (slot != NULL) { | 659 if (slot != NULL) { |
659 switch (slot->type()) { | 660 switch (slot->type()) { |
660 case Slot::PARAMETER: | 661 case Slot::PARAMETER: |
661 case Slot::LOCAL: | 662 case Slot::LOCAL: |
662 if (mode == Variable::CONST) { | 663 if (mode == Variable::CONST) { |
663 __ mov(Operand(ebp, SlotOffset(slot)), | 664 __ mov(Operand(ebp, SlotOffset(slot)), |
664 Immediate(Factory::the_hole_value())); | 665 Immediate(Factory::the_hole_value())); |
665 } else if (function != NULL) { | 666 } else if (function != NULL) { |
666 VisitForAccumulatorValue(function); | 667 VisitForAccumulatorValue(function); |
667 __ mov(Operand(ebp, SlotOffset(slot)), result_register()); | 668 __ mov(Operand(ebp, SlotOffset(slot)), result_register()); |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
807 __ j(not_equal, &next_test); | 808 __ j(not_equal, &next_test); |
808 __ Drop(1); // Switch value is no longer needed. | 809 __ Drop(1); // Switch value is no longer needed. |
809 __ jmp(clause->body_target()->entry_label()); | 810 __ jmp(clause->body_target()->entry_label()); |
810 __ bind(&slow_case); | 811 __ bind(&slow_case); |
811 } | 812 } |
812 | 813 |
813 // Record position before stub call for type feedback. | 814 // Record position before stub call for type feedback. |
814 SetSourcePosition(clause->position()); | 815 SetSourcePosition(clause->position()); |
815 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); | 816 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); |
816 EmitCallIC(ic, &patch_site); | 817 EmitCallIC(ic, &patch_site); |
817 | |
818 __ test(eax, Operand(eax)); | 818 __ test(eax, Operand(eax)); |
819 __ j(not_equal, &next_test); | 819 __ j(not_equal, &next_test); |
820 __ Drop(1); // Switch value is no longer needed. | 820 __ Drop(1); // Switch value is no longer needed. |
821 __ jmp(clause->body_target()->entry_label()); | 821 __ jmp(clause->body_target()->entry_label()); |
822 } | 822 } |
823 | 823 |
824 // Discard the test value and jump to the default if present, otherwise to | 824 // Discard the test value and jump to the default if present, otherwise to |
825 // the end of the statement. | 825 // the end of the statement. |
826 __ bind(&next_test); | 826 __ bind(&next_test); |
827 __ Drop(1); // Switch value is no longer needed. | 827 __ Drop(1); // Switch value is no longer needed. |
(...skipping 1555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2383 __ bind(&call); | 2383 __ bind(&call); |
2384 } | 2384 } |
2385 | 2385 |
2386 EmitCallWithStub(expr); | 2386 EmitCallWithStub(expr); |
2387 } else if (fun->AsProperty() != NULL) { | 2387 } else if (fun->AsProperty() != NULL) { |
2388 // Call to an object property. | 2388 // Call to an object property. |
2389 Property* prop = fun->AsProperty(); | 2389 Property* prop = fun->AsProperty(); |
2390 Literal* key = prop->key()->AsLiteral(); | 2390 Literal* key = prop->key()->AsLiteral(); |
2391 if (key != NULL && key->handle()->IsSymbol()) { | 2391 if (key != NULL && key->handle()->IsSymbol()) { |
2392 // Call to a named property, use call IC. | 2392 // Call to a named property, use call IC. |
2393 VisitForStackValue(prop->obj()); | 2393 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2394 VisitForStackValue(prop->obj()); |
| 2395 } |
2394 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); | 2396 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); |
2395 } else { | 2397 } else { |
2396 // Call to a keyed property. | 2398 // Call to a keyed property. |
2397 // For a synthetic property use keyed load IC followed by function call, | 2399 // For a synthetic property use keyed load IC followed by function call, |
2398 // for a regular property use keyed EmitCallIC. | 2400 // for a regular property use keyed EmitCallIC. |
2399 if (prop->is_synthetic()) { | 2401 if (prop->is_synthetic()) { |
2400 // Do not visit the object and key subexpressions (they are shared | 2402 // Do not visit the object and key subexpressions (they are shared |
2401 // by all occurrences of the same rewritten parameter). | 2403 // by all occurrences of the same rewritten parameter). |
2402 ASSERT(prop->obj()->AsVariableProxy() != NULL); | 2404 ASSERT(prop->obj()->AsVariableProxy() != NULL); |
2403 ASSERT(prop->obj()->AsVariableProxy()->var()->AsSlot() != NULL); | 2405 ASSERT(prop->obj()->AsVariableProxy()->var()->AsSlot() != NULL); |
(...skipping 990 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3394 Immediate(String::kContainsCachedArrayIndexMask)); | 3396 Immediate(String::kContainsCachedArrayIndexMask)); |
3395 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 3397 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
3396 Split(zero, if_true, if_false, fall_through); | 3398 Split(zero, if_true, if_false, fall_through); |
3397 | 3399 |
3398 context()->Plug(if_true, if_false); | 3400 context()->Plug(if_true, if_false); |
3399 } | 3401 } |
3400 | 3402 |
3401 | 3403 |
3402 void FullCodeGenerator::EmitGetCachedArrayIndex(ZoneList<Expression*>* args) { | 3404 void FullCodeGenerator::EmitGetCachedArrayIndex(ZoneList<Expression*>* args) { |
3403 ASSERT(args->length() == 1); | 3405 ASSERT(args->length() == 1); |
3404 | |
3405 VisitForAccumulatorValue(args->at(0)); | 3406 VisitForAccumulatorValue(args->at(0)); |
3406 | 3407 |
3407 if (FLAG_debug_code) { | 3408 if (FLAG_debug_code) { |
3408 __ AbortIfNotString(eax); | 3409 __ AbortIfNotString(eax); |
3409 } | 3410 } |
3410 | 3411 |
3411 __ mov(eax, FieldOperand(eax, String::kHashFieldOffset)); | 3412 __ mov(eax, FieldOperand(eax, String::kHashFieldOffset)); |
3412 __ IndexFromHash(eax, eax); | 3413 __ IndexFromHash(eax, eax); |
3413 | 3414 |
3414 context()->Plug(eax); | 3415 context()->Plug(eax); |
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3784 Comment cmnt(masm_, "[ UnaryOperation (NOT)"); | 3785 Comment cmnt(masm_, "[ UnaryOperation (NOT)"); |
3785 if (context()->IsEffect()) { | 3786 if (context()->IsEffect()) { |
3786 // Unary NOT has no side effects so it's only necessary to visit the | 3787 // Unary NOT has no side effects so it's only necessary to visit the |
3787 // subexpression. Match the optimizing compiler by not branching. | 3788 // subexpression. Match the optimizing compiler by not branching. |
3788 VisitForEffect(expr->expression()); | 3789 VisitForEffect(expr->expression()); |
3789 } else { | 3790 } else { |
3790 Label materialize_true, materialize_false; | 3791 Label materialize_true, materialize_false; |
3791 Label* if_true = NULL; | 3792 Label* if_true = NULL; |
3792 Label* if_false = NULL; | 3793 Label* if_false = NULL; |
3793 Label* fall_through = NULL; | 3794 Label* fall_through = NULL; |
| 3795 |
3794 // Notice that the labels are swapped. | 3796 // Notice that the labels are swapped. |
3795 context()->PrepareTest(&materialize_true, &materialize_false, | 3797 context()->PrepareTest(&materialize_true, &materialize_false, |
3796 &if_false, &if_true, &fall_through); | 3798 &if_false, &if_true, &fall_through); |
3797 if (context()->IsTest()) ForwardBailoutToChild(expr); | 3799 if (context()->IsTest()) ForwardBailoutToChild(expr); |
3798 VisitForControl(expr->expression(), if_true, if_false, fall_through); | 3800 VisitForControl(expr->expression(), if_true, if_false, fall_through); |
3799 context()->Plug(if_false, if_true); // Labels swapped. | 3801 context()->Plug(if_false, if_true); // Labels swapped. |
3800 } | 3802 } |
3801 break; | 3803 break; |
3802 } | 3804 } |
3803 | 3805 |
(...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4379 __ nop(); // Signals no inlined code. | 4381 __ nop(); // Signals no inlined code. |
4380 break; | 4382 break; |
4381 default: | 4383 default: |
4382 // Do nothing. | 4384 // Do nothing. |
4383 break; | 4385 break; |
4384 } | 4386 } |
4385 } | 4387 } |
4386 | 4388 |
4387 | 4389 |
4388 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) { | 4390 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) { |
| 4391 switch (ic->kind()) { |
| 4392 case Code::LOAD_IC: |
| 4393 __ IncrementCounter(&Counters::named_load_full, 1); |
| 4394 break; |
| 4395 case Code::KEYED_LOAD_IC: |
| 4396 __ IncrementCounter(&Counters::keyed_load_full, 1); |
| 4397 break; |
| 4398 case Code::STORE_IC: |
| 4399 __ IncrementCounter(&Counters::named_store_full, 1); |
| 4400 break; |
| 4401 case Code::KEYED_STORE_IC: |
| 4402 __ IncrementCounter(&Counters::keyed_store_full, 1); |
| 4403 default: |
| 4404 break; |
| 4405 } |
| 4406 |
4389 __ call(ic, RelocInfo::CODE_TARGET); | 4407 __ call(ic, RelocInfo::CODE_TARGET); |
4390 if (patch_site != NULL && patch_site->is_bound()) { | 4408 if (patch_site != NULL && patch_site->is_bound()) { |
4391 patch_site->EmitPatchInfo(); | 4409 patch_site->EmitPatchInfo(); |
4392 } else { | 4410 } else { |
4393 __ nop(); // Signals no inlined code. | 4411 __ nop(); // Signals no inlined code. |
4394 } | 4412 } |
4395 } | 4413 } |
4396 | 4414 |
4397 | 4415 |
4398 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { | 4416 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4435 // And return. | 4453 // And return. |
4436 __ ret(0); | 4454 __ ret(0); |
4437 } | 4455 } |
4438 | 4456 |
4439 | 4457 |
4440 #undef __ | 4458 #undef __ |
4441 | 4459 |
4442 } } // namespace v8::internal | 4460 } } // namespace v8::internal |
4443 | 4461 |
4444 #endif // V8_TARGET_ARCH_IA32 | 4462 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |