Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(36)

Side by Side Diff: src/codegen-ia32.cc

Issue 16412: Experimental: push the new code generator infrastructure into the... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: Created 12 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/codegen-ia32.h ('k') | src/jump-target.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 3743 matching lines...) Expand 10 before | Expand all | Expand 10 after
3754 " (is_increment %s)\n", 3754 " (is_increment %s)\n",
3755 result_offset_, 3755 result_offset_,
3756 is_postfix_ ? "true" : "false", 3756 is_postfix_ ? "true" : "false",
3757 is_increment_ ? "true" : "false"); 3757 is_increment_ ? "true" : "false");
3758 } 3758 }
3759 #endif 3759 #endif
3760 }; 3760 };
3761 3761
3762 3762
3763 void DeferredCountOperation::Generate() { 3763 void DeferredCountOperation::Generate() {
3764 // The argument is actually passed in eax. 3764 CodeGenerator* cgen = generator();
3765 enter()->Bind(); 3765
3766 VirtualFrame::SpilledScope spilled_scope(generator()); 3766 // The argument will be passed in a register and the result returned in
3767 // the same register.
3768 Result value(cgen);
3769 enter()->Bind(&value);
3770 ASSERT(value.is_register());
3771 Register target = value.reg();
3772 value.ToRegister(eax); // The stubs below expect their argument in eax.
3773
3767 if (is_postfix_) { 3774 if (is_postfix_) {
3768 RevertToNumberStub to_number_stub(is_increment_); 3775 RevertToNumberStub to_number_stub(is_increment_);
3769 generator()->frame()->CallStub(&to_number_stub, 0); 3776 value = generator()->frame()->CallStub(&to_number_stub, &value, 0);
3770 } 3777 }
3778
3771 CounterOpStub stub(result_offset_, is_postfix_, is_increment_); 3779 CounterOpStub stub(result_offset_, is_postfix_, is_increment_);
3772 generator()->frame()->CallStub(&stub, 0); 3780 value = generator()->frame()->CallStub(&stub, &value, 0);
3773 // The result is actually returned in eax. 3781 value.ToRegister(target);
3774 exit()->Jump(); 3782 exit()->Jump(&value);
3775 } 3783 }
3776 3784
3777 3785
3778 void CodeGenerator::VisitCountOperation(CountOperation* node) { 3786 void CodeGenerator::VisitCountOperation(CountOperation* node) {
3779 VirtualFrame::SpilledScope spilled_scope(this);
3780 Comment cmnt(masm_, "[ CountOperation"); 3787 Comment cmnt(masm_, "[ CountOperation");
3781 3788
3782 bool is_postfix = node->is_postfix(); 3789 bool is_postfix = node->is_postfix();
3783 bool is_increment = node->op() == Token::INC; 3790 bool is_increment = node->op() == Token::INC;
3784 3791
3785 Variable* var = node->expression()->AsVariableProxy()->AsVariable(); 3792 Variable* var = node->expression()->AsVariableProxy()->AsVariable();
3786 bool is_const = (var != NULL && var->mode() == Variable::CONST); 3793 bool is_const = (var != NULL && var->mode() == Variable::CONST);
3787 3794
3788 // Postfix: Make room for the result. 3795 // Postfix: Make room for the result.
3789 if (is_postfix) { 3796 if (is_postfix) {
3790 frame_->EmitPush(Immediate(0)); 3797 frame_->Push(Handle<Object>(Smi::FromInt(0)));
3791 } 3798 }
3792 3799
3793 { Reference target(this, node->expression()); 3800 { Reference target(this, node->expression());
3794 if (target.is_illegal()) { 3801 if (target.is_illegal()) {
3795 // Spoof the virtual frame to have the expected height (one higher 3802 // Spoof the virtual frame to have the expected height (one higher
3796 // than on entry). 3803 // than on entry).
3797 if (!is_postfix) { 3804 if (!is_postfix) {
3798 frame_->EmitPush(Immediate(Smi::FromInt(0))); 3805 frame_->Push(Handle<Object>(Smi::FromInt(0)));
3799 } 3806 }
3800 return; 3807 return;
3801 } 3808 }
3802 target.GetValueAndSpill(NOT_INSIDE_TYPEOF); 3809 target.TakeValue(NOT_INSIDE_TYPEOF);
3803 3810
3804 DeferredCountOperation* deferred = 3811 DeferredCountOperation* deferred =
3805 new DeferredCountOperation(this, is_postfix, is_increment, 3812 new DeferredCountOperation(this, is_postfix, is_increment,
3806 target.size() * kPointerSize); 3813 target.size() * kPointerSize);
3807 3814
3808 frame_->EmitPop(eax); // Load TOS into eax for calculations below 3815 Result value = frame_->Pop();
3816 value.ToRegister();
3817 ASSERT(value.is_valid());
3809 3818
3810 // Postfix: Store the old value as the result. 3819 // Postfix: Store the old value as the result.
3811 if (is_postfix) { 3820 if (is_postfix) {
3812 __ mov(frame_->ElementAt(target.size()), eax); 3821 Result old_value = value;
3822 frame_->SetElementAt(target.size(), &old_value);
3813 } 3823 }
3814 3824
3815 // Perform optimistic increment/decrement. 3825 // Perform optimistic increment/decrement. Ensure the value is
3826 // writable.
3827 frame_->Spill(value.reg());
3828 ASSERT(allocator_->count(value.reg()) == 1);
3816 if (is_increment) { 3829 if (is_increment) {
3817 __ add(Operand(eax), Immediate(Smi::FromInt(1))); 3830 __ add(Operand(value.reg()), Immediate(Smi::FromInt(1)));
3818 } else { 3831 } else {
3819 __ sub(Operand(eax), Immediate(Smi::FromInt(1))); 3832 __ sub(Operand(value.reg()), Immediate(Smi::FromInt(1)));
3820 } 3833 }
3821 3834
3822 // If the count operation didn't overflow and the result is a 3835 // If the count operation didn't overflow and the result is a
3823 // valid smi, we're done. Otherwise, we jump to the deferred 3836 // valid smi, we're done. Otherwise, we jump to the deferred
3824 // slow-case code. 3837 // slow-case code.
3825 deferred->enter()->Branch(overflow, not_taken); 3838 deferred->enter()->Branch(overflow, &value, not_taken);
3826 __ test(eax, Immediate(kSmiTagMask)); 3839 __ test(value.reg(), Immediate(kSmiTagMask));
3827 deferred->enter()->Branch(not_zero, not_taken); 3840 deferred->enter()->Branch(not_zero, &value, not_taken);
3828 3841
3829 // Store the new value in the target if not const. 3842 // Store the new value in the target if not const.
3830 deferred->exit()->Bind(); 3843 deferred->exit()->Bind(&value);
3831 frame_->EmitPush(eax); // Push the new value to TOS 3844 frame_->Push(&value);
3832 if (!is_const) target.SetValue(NOT_CONST_INIT); 3845 if (!is_const) {
3846 target.SetValue(NOT_CONST_INIT);
3847 }
3833 } 3848 }
3834 3849
3835 // Postfix: Discard the new value and use the old. 3850 // Postfix: Discard the new value and use the old.
3836 if (is_postfix) { 3851 if (is_postfix) {
3837 frame_->Drop(); 3852 frame_->Drop();
3838 } 3853 }
3839 } 3854 }
3840 3855
3841 3856
3842 void CodeGenerator::VisitBinaryOperation(BinaryOperation* node) { 3857 void CodeGenerator::VisitBinaryOperation(BinaryOperation* node) {
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
4296 frame->EmitPush(eax); // IC call leaves result in eax, push it out 4311 frame->EmitPush(eax); // IC call leaves result in eax, push it out
4297 break; 4312 break;
4298 } 4313 }
4299 4314
4300 default: 4315 default:
4301 UNREACHABLE(); 4316 UNREACHABLE();
4302 } 4317 }
4303 } 4318 }
4304 4319
4305 4320
4321 void Reference::TakeValue(TypeofState typeof_state) {
4322 // For non-constant frame-allocated slots, we invalidate the value in the
4323 // slot. For all others, we fall back on GetValue.
4324 ASSERT(!cgen_->in_spilled_code());
4325 ASSERT(!is_illegal());
4326 ASSERT(!cgen_->has_cc());
4327 if (type_ != SLOT) {
4328 GetValue(typeof_state);
4329 return;
4330 }
4331
4332 Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot();
4333 ASSERT(slot != NULL);
4334 if (slot->type() == Slot::LOOKUP ||
4335 slot->type() == Slot::CONTEXT ||
4336 slot->var()->mode() == Variable::CONST) {
4337 GetValue(typeof_state);
4338 return;
4339 }
4340
4341 // Only non-constant, frame-allocated parameters and locals can reach
4342 // here.
4343 if (slot->type() == Slot::PARAMETER) {
4344 cgen_->frame()->TakeParameterAt(slot->index());
4345 } else {
4346 ASSERT(slot->type() == Slot::LOCAL);
4347 cgen_->frame()->TakeLocalAt(slot->index());
4348 }
4349 }
4350
4351
4306 void Reference::SetValue(InitState init_state) { 4352 void Reference::SetValue(InitState init_state) {
4307 ASSERT(!is_illegal()); 4353 ASSERT(!is_illegal());
4308 ASSERT(!cgen_->has_cc()); 4354 ASSERT(!cgen_->has_cc());
4309 MacroAssembler* masm = cgen_->masm(); 4355 MacroAssembler* masm = cgen_->masm();
4310 VirtualFrame* frame = cgen_->frame(); 4356 VirtualFrame* frame = cgen_->frame();
4311 switch (type_) { 4357 switch (type_) {
4312 case SLOT: { 4358 case SLOT: {
4313 Comment cmnt(masm, "[ Store to Slot"); 4359 Comment cmnt(masm, "[ Store to Slot");
4314 Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot(); 4360 Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot();
4315 ASSERT(slot != NULL); 4361 ASSERT(slot != NULL);
(...skipping 1408 matching lines...) Expand 10 before | Expand all | Expand 10 after
5724 5770
5725 // Slow-case: Go through the JavaScript implementation. 5771 // Slow-case: Go through the JavaScript implementation.
5726 __ bind(&slow); 5772 __ bind(&slow);
5727 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); 5773 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
5728 } 5774 }
5729 5775
5730 5776
5731 #undef __ 5777 #undef __
5732 5778
5733 } } // namespace v8::internal 5779 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/codegen-ia32.h ('k') | src/jump-target.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698