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

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

Issue 55003: Make VirtualFrame::CallStub on IA32 responsible for moving arguments... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 9 months 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-arm.cc ('k') | src/virtual-frame.cc » ('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-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 1490 matching lines...) Expand 10 before | Expand all | Expand 10 after
1501 // CompareStub and the inline code both support all values of cc. 1501 // CompareStub and the inline code both support all values of cc.
1502 } 1502 }
1503 // Implement comparison against a constant Smi, inlining the case 1503 // Implement comparison against a constant Smi, inlining the case
1504 // where both sides are Smis. 1504 // where both sides are Smis.
1505 left_side.ToRegister(); 1505 left_side.ToRegister();
1506 ASSERT(left_side.is_valid()); 1506 ASSERT(left_side.is_valid());
1507 JumpTarget is_smi(this); 1507 JumpTarget is_smi(this);
1508 __ test(left_side.reg(), Immediate(kSmiTagMask)); 1508 __ test(left_side.reg(), Immediate(kSmiTagMask));
1509 is_smi.Branch(zero, &left_side, &right_side, taken); 1509 is_smi.Branch(zero, &left_side, &right_side, taken);
1510 1510
1511 // Setup and call the compare stub, which expects arguments in edx 1511 // Setup and call the compare stub, which expects its arguments
1512 // and eax. 1512 // in registers.
1513 CompareStub stub(cc, strict); 1513 CompareStub stub(cc, strict);
1514 left_side.ToRegister(edx); // Only left_side currently uses a register. 1514 Result result = frame_->CallStub(&stub, &left_side, &right_side);
1515 right_side.ToRegister(eax); // left_side is not in eax. eax is free.
1516 Result result = frame_->CallStub(&stub, &left_side, &right_side, 0);
1517 result.ToRegister(); 1515 result.ToRegister();
1518 __ cmp(result.reg(), 0); 1516 __ cmp(result.reg(), 0);
1519 result.Unuse(); 1517 result.Unuse();
1520 dest->true_target()->Branch(cc); 1518 dest->true_target()->Branch(cc);
1521 dest->false_target()->Jump(); 1519 dest->false_target()->Jump();
1522 1520
1523 is_smi.Bind(&left_side, &right_side); 1521 is_smi.Bind(&left_side, &right_side);
1524 left_side.ToRegister(); 1522 left_side.ToRegister();
1525 // Test smi equality and comparison by signed int comparison. 1523 // Test smi equality and comparison by signed int comparison.
1526 if (IsUnsafeSmi(right_side.handle())) { 1524 if (IsUnsafeSmi(right_side.handle())) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1581 if (!known_non_smi) { 1579 if (!known_non_smi) {
1582 // Check for the smi case. 1580 // Check for the smi case.
1583 Result temp = allocator_->Allocate(); 1581 Result temp = allocator_->Allocate();
1584 ASSERT(temp.is_valid()); 1582 ASSERT(temp.is_valid());
1585 __ mov(temp.reg(), left_side.reg()); 1583 __ mov(temp.reg(), left_side.reg());
1586 __ or_(temp.reg(), Operand(right_side.reg())); 1584 __ or_(temp.reg(), Operand(right_side.reg()));
1587 __ test(temp.reg(), Immediate(kSmiTagMask)); 1585 __ test(temp.reg(), Immediate(kSmiTagMask));
1588 temp.Unuse(); 1586 temp.Unuse();
1589 is_smi.Branch(zero, &left_side, &right_side, taken); 1587 is_smi.Branch(zero, &left_side, &right_side, taken);
1590 } 1588 }
1591 // When non-smi, call out to the compare stub. "parameters" setup by 1589 // When non-smi, call out to the compare stub, which expects its
1592 // calling code in edx and eax and "result" is returned in the flags. 1590 // arguments in registers.
1593 if (!left_side.reg().is(eax)) {
1594 right_side.ToRegister(eax);
1595 left_side.ToRegister(edx);
1596 } else if (!right_side.reg().is(edx)) {
1597 left_side.ToRegister(edx);
1598 right_side.ToRegister(eax);
1599 } else {
1600 frame_->Spill(eax); // Can be multiply referenced, even now.
1601 frame_->Spill(edx);
1602 __ xchg(eax, edx);
1603 // If left_side and right_side become real (non-dummy) arguments
1604 // to CallStub, they need to be swapped in this case.
1605 }
1606 CompareStub stub(cc, strict); 1591 CompareStub stub(cc, strict);
1607 Result answer = frame_->CallStub(&stub, &right_side, &left_side, 0); 1592 Result answer = frame_->CallStub(&stub, &left_side, &right_side);
1608 if (cc == equal) { 1593 if (cc == equal) {
1609 __ test(answer.reg(), Operand(answer.reg())); 1594 __ test(answer.reg(), Operand(answer.reg()));
1610 } else { 1595 } else {
1611 __ cmp(answer.reg(), 0); 1596 __ cmp(answer.reg(), 0);
1612 } 1597 }
1613 answer.Unuse(); 1598 answer.Unuse();
1614 if (known_non_smi) { 1599 if (known_non_smi) {
1615 dest->Split(cc); 1600 dest->Split(cc);
1616 } else { 1601 } else {
1617 dest->true_target()->Branch(cc); 1602 dest->true_target()->Branch(cc);
(...skipping 2767 matching lines...) Expand 10 before | Expand all | Expand 10 after
4385 // Check if the object is a JS array or not. 4370 // Check if the object is a JS array or not.
4386 __ CmpObjectType(value.reg(), JS_ARRAY_TYPE, temp.reg()); 4371 __ CmpObjectType(value.reg(), JS_ARRAY_TYPE, temp.reg());
4387 value.Unuse(); 4372 value.Unuse();
4388 temp.Unuse(); 4373 temp.Unuse();
4389 destination()->Split(equal); 4374 destination()->Split(equal);
4390 } 4375 }
4391 4376
4392 4377
4393 void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) { 4378 void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) {
4394 ASSERT(args->length() == 0); 4379 ASSERT(args->length() == 0);
4395 Result initial_value = allocator()->Allocate(eax);
4396 ASSERT(initial_value.is_valid());
4397 __ Set(initial_value.reg(),
4398 Immediate(Smi::FromInt(scope_->num_parameters())));
4399 // ArgumentsAccessStub takes the parameter count as an input argument 4380 // ArgumentsAccessStub takes the parameter count as an input argument
4400 // in register eax. 4381 // in register eax. Create a constant result for it.
4382 Result count(Handle<Smi>(Smi::FromInt(scope_->num_parameters())), this);
4401 // Call the shared stub to get to the arguments.length. 4383 // Call the shared stub to get to the arguments.length.
4402 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_LENGTH); 4384 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_LENGTH);
4403 Result result = frame_->CallStub(&stub, &initial_value, 0); 4385 Result result = frame_->CallStub(&stub, &count);
4404 frame_->Push(&result); 4386 frame_->Push(&result);
4405 } 4387 }
4406 4388
4407 4389
4408 void CodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) { 4390 void CodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) {
4409 ASSERT(args->length() == 1); 4391 ASSERT(args->length() == 1);
4410 JumpTarget leave(this); 4392 JumpTarget leave(this);
4411 Load(args->at(0)); // Load the object. 4393 Load(args->at(0)); // Load the object.
4412 frame_->Dup(); 4394 frame_->Dup();
4413 Result object = frame_->Pop(); 4395 Result object = frame_->Pop();
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
4468 4450
4469 // Leave. 4451 // Leave.
4470 leave.Bind(&value); 4452 leave.Bind(&value);
4471 frame_->Push(&value); 4453 frame_->Push(&value);
4472 } 4454 }
4473 4455
4474 4456
4475 void CodeGenerator::GenerateArgumentsAccess(ZoneList<Expression*>* args) { 4457 void CodeGenerator::GenerateArgumentsAccess(ZoneList<Expression*>* args) {
4476 ASSERT(args->length() == 1); 4458 ASSERT(args->length() == 1);
4477 4459
4478 // Load the key into edx and set eax to the formal parameters count 4460 // ArgumentsAccessStub expects the key in edx and the formal
4479 // for the currently executing function. 4461 // parameter count in eax.
4480 Load(args->at(0)); 4462 Load(args->at(0));
4481 Result key = frame_->Pop(); 4463 Result key = frame_->Pop();
4482 key.ToRegister(edx); 4464 // Explicitly create a constant result.
4483 4465 Result count(Handle<Smi>(Smi::FromInt(scope_->num_parameters())), this);
4484 Result parameters_count = allocator()->Allocate(eax);
4485 ASSERT(parameters_count.is_valid());
4486 __ Set(parameters_count.reg(),
4487 Immediate(Smi::FromInt(scope_->num_parameters())));
4488
4489 // Call the shared stub to get to arguments[key]. 4466 // Call the shared stub to get to arguments[key].
4490 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT); 4467 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT);
4491 Result result = frame_->CallStub(&stub, &parameters_count, &key, 0); 4468 Result result = frame_->CallStub(&stub, &key, &count);
4492 frame_->Push(&result); 4469 frame_->Push(&result);
4493 } 4470 }
4494 4471
4495 4472
4496 void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) { 4473 void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) {
4497 ASSERT(args->length() == 2); 4474 ASSERT(args->length() == 2);
4498 4475
4499 // Load the two objects into registers and perform the comparison. 4476 // Load the two objects into registers and perform the comparison.
4500 Load(args->at(0)); 4477 Load(args->at(0));
4501 Load(args->at(1)); 4478 Load(args->at(1));
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
4640 case Token::NOT: 4617 case Token::NOT:
4641 case Token::DELETE: 4618 case Token::DELETE:
4642 case Token::TYPEOF: 4619 case Token::TYPEOF:
4643 UNREACHABLE(); // handled above 4620 UNREACHABLE(); // handled above
4644 break; 4621 break;
4645 4622
4646 case Token::SUB: { 4623 case Token::SUB: {
4647 UnarySubStub stub; 4624 UnarySubStub stub;
4648 // TODO(1222589): remove dependency of TOS being cached inside stub 4625 // TODO(1222589): remove dependency of TOS being cached inside stub
4649 Result operand = frame_->Pop(); 4626 Result operand = frame_->Pop();
4650 operand.ToRegister(eax); 4627 Result answer = frame_->CallStub(&stub, &operand);
4651 Result answer = frame_->CallStub(&stub, &operand, 0);
4652 frame_->Push(&answer); 4628 frame_->Push(&answer);
4653 break; 4629 break;
4654 } 4630 }
4655 4631
4656 case Token::BIT_NOT: { 4632 case Token::BIT_NOT: {
4657 // Smi check. 4633 // Smi check.
4658 JumpTarget smi_label(this); 4634 JumpTarget smi_label(this);
4659 JumpTarget continue_label(this); 4635 JumpTarget continue_label(this);
4660 Result operand = frame_->Pop(); 4636 Result operand = frame_->Pop();
4661 operand.ToRegister(); 4637 operand.ToRegister();
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
4774 } 4750 }
4775 #endif 4751 #endif
4776 }; 4752 };
4777 4753
4778 4754
4779 void DeferredCountOperation::Generate() { 4755 void DeferredCountOperation::Generate() {
4780 CodeGenerator* cgen = generator(); 4756 CodeGenerator* cgen = generator();
4781 4757
4782 Result value(cgen); 4758 Result value(cgen);
4783 enter()->Bind(&value); 4759 enter()->Bind(&value);
4784 value.ToRegister(eax); // The stubs below expect their argument in eax.
4785
4786 if (is_postfix_) { 4760 if (is_postfix_) {
4787 RevertToNumberStub to_number_stub(is_increment_); 4761 RevertToNumberStub to_number_stub(is_increment_);
4788 value = generator()->frame()->CallStub(&to_number_stub, &value, 0); 4762 value = generator()->frame()->CallStub(&to_number_stub, &value);
4789 } 4763 }
4790 4764
4791 CounterOpStub stub(result_offset_, is_postfix_, is_increment_); 4765 CounterOpStub stub(result_offset_, is_postfix_, is_increment_);
4792 value = generator()->frame()->CallStub(&stub, &value, 0); 4766 value = generator()->frame()->CallStub(&stub, &value);
4793 exit_.Jump(&value); 4767 exit_.Jump(&value);
4794 } 4768 }
4795 4769
4796 4770
4797 void CodeGenerator::VisitCountOperation(CountOperation* node) { 4771 void CodeGenerator::VisitCountOperation(CountOperation* node) {
4798 Comment cmnt(masm_, "[ CountOperation"); 4772 Comment cmnt(masm_, "[ CountOperation");
4799 4773
4800 bool is_postfix = node->is_postfix(); 4774 bool is_postfix = node->is_postfix();
4801 bool is_increment = node->op() == Token::INC; 4775 bool is_increment = node->op() == Token::INC;
4802 4776
(...skipping 2291 matching lines...) Expand 10 before | Expand all | Expand 10 after
7094 7068
7095 // Slow-case: Go through the JavaScript implementation. 7069 // Slow-case: Go through the JavaScript implementation.
7096 __ bind(&slow); 7070 __ bind(&slow);
7097 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); 7071 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
7098 } 7072 }
7099 7073
7100 7074
7101 #undef __ 7075 #undef __
7102 7076
7103 } } // namespace v8::internal 7077 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/codegen-arm.cc ('k') | src/virtual-frame.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698