| 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 |