| 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 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 for (int i = 0; i < kPadding; ++i) { | 111 for (int i = 0; i < kPadding; ++i) { |
| 112 masm_->int3(); | 112 masm_->int3(); |
| 113 } | 113 } |
| 114 #endif | 114 #endif |
| 115 } | 115 } |
| 116 } | 116 } |
| 117 | 117 |
| 118 | 118 |
| 119 void FastCodeGenerator::Move(Location destination, Slot* source) { | 119 void FastCodeGenerator::Move(Location destination, Slot* source) { |
| 120 switch (destination.type()) { | 120 switch (destination.type()) { |
| 121 case Location::UNINITIALIZED: | 121 case Location::kUninitialized: |
| 122 UNREACHABLE(); | 122 UNREACHABLE(); |
| 123 case Location::EFFECT: | 123 case Location::kEffect: |
| 124 break; | 124 break; |
| 125 case Location::VALUE: | 125 case Location::kValue: |
| 126 __ push(Operand(rbp, SlotOffset(source))); | 126 __ push(Operand(rbp, SlotOffset(source))); |
| 127 break; | 127 break; |
| 128 } | 128 } |
| 129 } | 129 } |
| 130 | 130 |
| 131 | 131 |
| 132 void FastCodeGenerator::Move(Location destination, Literal* expr) { | 132 void FastCodeGenerator::Move(Location destination, Literal* expr) { |
| 133 switch (destination.type()) { | 133 switch (destination.type()) { |
| 134 case Location::UNINITIALIZED: | 134 case Location::kUninitialized: |
| 135 UNREACHABLE(); | 135 UNREACHABLE(); |
| 136 case Location::EFFECT: | 136 case Location::kEffect: |
| 137 break; | 137 break; |
| 138 case Location::VALUE: | 138 case Location::kValue: |
| 139 __ Push(expr->handle()); | 139 __ Push(expr->handle()); |
| 140 break; | 140 break; |
| 141 } | 141 } |
| 142 } | 142 } |
| 143 | 143 |
| 144 | 144 |
| 145 void FastCodeGenerator::Move(Slot* destination, Location source) { | 145 void FastCodeGenerator::Move(Slot* destination, Location source) { |
| 146 switch (source.type()) { | 146 switch (source.type()) { |
| 147 case Location::UNINITIALIZED: // Fall through. | 147 case Location::kUninitialized: // Fall through. |
| 148 case Location::EFFECT: | 148 case Location::kEffect: |
| 149 UNREACHABLE(); | 149 UNREACHABLE(); |
| 150 case Location::VALUE: | 150 case Location::kValue: |
| 151 __ pop(Operand(rbp, SlotOffset(destination))); | 151 __ pop(Operand(rbp, SlotOffset(destination))); |
| 152 break; | 152 break; |
| 153 } | 153 } |
| 154 } | 154 } |
| 155 | 155 |
| 156 | 156 |
| 157 void FastCodeGenerator::DropAndMove(Location destination, Register source) { | 157 void FastCodeGenerator::DropAndMove(Location destination, Register source) { |
| 158 switch (destination.type()) { | 158 switch (destination.type()) { |
| 159 case Location::UNINITIALIZED: | 159 case Location::kUninitialized: |
| 160 UNREACHABLE(); | 160 UNREACHABLE(); |
| 161 case Location::EFFECT: | 161 case Location::kEffect: |
| 162 __ addq(rsp, Immediate(kPointerSize)); | 162 __ addq(rsp, Immediate(kPointerSize)); |
| 163 break; | 163 break; |
| 164 case Location::VALUE: | 164 case Location::kValue: |
| 165 __ movq(Operand(rsp, 0), source); | 165 __ movq(Operand(rsp, 0), source); |
| 166 break; | 166 break; |
| 167 } | 167 } |
| 168 } | 168 } |
| 169 | 169 |
| 170 | 170 |
| 171 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 171 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
| 172 // Call the runtime to declare the globals. | 172 // Call the runtime to declare the globals. |
| 173 __ push(rsi); // The context is the first argument. | 173 __ push(rsi); // The context is the first argument. |
| 174 __ Push(pairs); | 174 __ Push(pairs); |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 357 Smi::FromInt(0)); | 357 Smi::FromInt(0)); |
| 358 Visit(value); | 358 Visit(value); |
| 359 ASSERT(value->location().is_value()); | 359 ASSERT(value->location().is_value()); |
| 360 __ CallRuntime(Runtime::kDefineAccessor, 4); | 360 __ CallRuntime(Runtime::kDefineAccessor, 4); |
| 361 __ movq(rax, Operand(rsp, 0)); // Restore result into rax. | 361 __ movq(rax, Operand(rsp, 0)); // Restore result into rax. |
| 362 break; | 362 break; |
| 363 default: UNREACHABLE(); | 363 default: UNREACHABLE(); |
| 364 } | 364 } |
| 365 } | 365 } |
| 366 switch (expr->location().type()) { | 366 switch (expr->location().type()) { |
| 367 case Location::UNINITIALIZED: | 367 case Location::kUninitialized: |
| 368 UNREACHABLE(); | 368 UNREACHABLE(); |
| 369 case Location::EFFECT: | 369 case Location::kEffect: |
| 370 if (result_saved) __ addq(rsp, Immediate(kPointerSize)); | 370 if (result_saved) __ addq(rsp, Immediate(kPointerSize)); |
| 371 break; | 371 break; |
| 372 case Location::VALUE: | 372 case Location::kValue: |
| 373 if (!result_saved) __ push(rax); | 373 if (!result_saved) __ push(rax); |
| 374 break; | 374 break; |
| 375 } | 375 } |
| 376 } | 376 } |
| 377 | 377 |
| 378 | 378 |
| 379 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { | 379 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { |
| 380 Comment cmnt(masm_, "[ ArrayLiteral"); | 380 Comment cmnt(masm_, "[ ArrayLiteral"); |
| 381 Label make_clone; | 381 Label make_clone; |
| 382 | 382 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 431 __ movq(rbx, Operand(rsp, 0)); // Copy of array literal. | 431 __ movq(rbx, Operand(rsp, 0)); // Copy of array literal. |
| 432 __ movq(rbx, FieldOperand(rbx, JSObject::kElementsOffset)); | 432 __ movq(rbx, FieldOperand(rbx, JSObject::kElementsOffset)); |
| 433 int offset = FixedArray::kHeaderSize + (i * kPointerSize); | 433 int offset = FixedArray::kHeaderSize + (i * kPointerSize); |
| 434 __ movq(FieldOperand(rbx, offset), rax); | 434 __ movq(FieldOperand(rbx, offset), rax); |
| 435 | 435 |
| 436 // Update the write barrier for the array store. | 436 // Update the write barrier for the array store. |
| 437 __ RecordWrite(rbx, offset, rax, rcx); | 437 __ RecordWrite(rbx, offset, rax, rcx); |
| 438 } | 438 } |
| 439 | 439 |
| 440 switch (expr->location().type()) { | 440 switch (expr->location().type()) { |
| 441 case Location::UNINITIALIZED: | 441 case Location::kUninitialized: |
| 442 UNREACHABLE(); | 442 UNREACHABLE(); |
| 443 case Location::EFFECT: | 443 case Location::kEffect: |
| 444 if (result_saved) __ addq(rsp, Immediate(kPointerSize)); | 444 if (result_saved) __ addq(rsp, Immediate(kPointerSize)); |
| 445 break; | 445 break; |
| 446 case Location::VALUE: | 446 case Location::kValue: |
| 447 if (!result_saved) __ push(rax); | 447 if (!result_saved) __ push(rax); |
| 448 break; | 448 break; |
| 449 } | 449 } |
| 450 } | 450 } |
| 451 | 451 |
| 452 | 452 |
| 453 void FastCodeGenerator::VisitAssignment(Assignment* expr) { | 453 void FastCodeGenerator::VisitAssignment(Assignment* expr) { |
| 454 Comment cmnt(masm_, "[ Assignment"); | 454 Comment cmnt(masm_, "[ Assignment"); |
| 455 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR); | 455 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR); |
| 456 | 456 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 487 if (rhs->AsLiteral() != NULL) { | 487 if (rhs->AsLiteral() != NULL) { |
| 488 // Two cases: 'temp <- (var = constant)', or 'var = constant' with a | 488 // Two cases: 'temp <- (var = constant)', or 'var = constant' with a |
| 489 // discarded result. Always perform the assignment. | 489 // discarded result. Always perform the assignment. |
| 490 __ Move(kScratchRegister, rhs->AsLiteral()->handle()); | 490 __ Move(kScratchRegister, rhs->AsLiteral()->handle()); |
| 491 __ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister); | 491 __ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister); |
| 492 Move(expr->location(), kScratchRegister); | 492 Move(expr->location(), kScratchRegister); |
| 493 } else { | 493 } else { |
| 494 ASSERT(rhs->location().is_value()); | 494 ASSERT(rhs->location().is_value()); |
| 495 Visit(rhs); | 495 Visit(rhs); |
| 496 switch (expr->location().type()) { | 496 switch (expr->location().type()) { |
| 497 case Location::UNINITIALIZED: | 497 case Location::kUninitialized: |
| 498 UNREACHABLE(); | 498 UNREACHABLE(); |
| 499 case Location::EFFECT: | 499 case Location::kEffect: |
| 500 // Case 'var = temp'. Discard right-hand-side temporary. | 500 // Case 'var = temp'. Discard right-hand-side temporary. |
| 501 Move(var->slot(), rhs->location()); | 501 Move(var->slot(), rhs->location()); |
| 502 break; | 502 break; |
| 503 case Location::VALUE: | 503 case Location::kValue: |
| 504 // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side | 504 // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side |
| 505 // temporary on the stack. | 505 // temporary on the stack. |
| 506 __ movq(kScratchRegister, Operand(rsp, 0)); | 506 __ movq(kScratchRegister, Operand(rsp, 0)); |
| 507 __ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister); | 507 __ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister); |
| 508 break; | 508 break; |
| 509 } | 509 } |
| 510 } | 510 } |
| 511 } | 511 } |
| 512 } | 512 } |
| 513 | 513 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 538 Visit(expr->key()); | 538 Visit(expr->key()); |
| 539 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 539 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
| 540 __ call(ic, RelocInfo::CODE_TARGET); | 540 __ call(ic, RelocInfo::CODE_TARGET); |
| 541 // By emitting a nop we make sure that we do not have a "test ..." | 541 // By emitting a nop we make sure that we do not have a "test ..." |
| 542 // instruction after the call it is treated specially by the LoadIC code. | 542 // instruction after the call it is treated specially by the LoadIC code. |
| 543 __ nop(); | 543 __ nop(); |
| 544 // Drop key left on the stack by IC. | 544 // Drop key left on the stack by IC. |
| 545 __ addq(rsp, Immediate(kPointerSize)); | 545 __ addq(rsp, Immediate(kPointerSize)); |
| 546 } | 546 } |
| 547 switch (expr->location().type()) { | 547 switch (expr->location().type()) { |
| 548 case Location::UNINITIALIZED: | 548 case Location::kUninitialized: |
| 549 UNREACHABLE(); | 549 UNREACHABLE(); |
| 550 case Location::VALUE: | 550 case Location::kValue: |
| 551 __ movq(Operand(rsp, 0), rax); | 551 __ movq(Operand(rsp, 0), rax); |
| 552 break; | 552 break; |
| 553 case Location::EFFECT: | 553 case Location::kEffect: |
| 554 __ addq(rsp, Immediate(kPointerSize)); | 554 __ addq(rsp, Immediate(kPointerSize)); |
| 555 break; | 555 break; |
| 556 } | 556 } |
| 557 } | 557 } |
| 558 | 558 |
| 559 | 559 |
| 560 void FastCodeGenerator::VisitCall(Call* expr) { | 560 void FastCodeGenerator::VisitCall(Call* expr) { |
| 561 Expression* fun = expr->expression(); | 561 Expression* fun = expr->expression(); |
| 562 ZoneList<Expression*>* args = expr->arguments(); | 562 ZoneList<Expression*>* args = expr->arguments(); |
| 563 Variable* var = fun->AsVariableProxy()->AsVariable(); | 563 Variable* var = fun->AsVariableProxy()->AsVariable(); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 662 | 662 |
| 663 // Compile the left-hand value into rax. Put it on the stack if we may | 663 // Compile the left-hand value into rax. Put it on the stack if we may |
| 664 // need it as the value of the whole expression. | 664 // need it as the value of the whole expression. |
| 665 if (left->AsLiteral() != NULL) { | 665 if (left->AsLiteral() != NULL) { |
| 666 __ Move(rax, left->AsLiteral()->handle()); | 666 __ Move(rax, left->AsLiteral()->handle()); |
| 667 if (destination.is_value()) __ push(rax); | 667 if (destination.is_value()) __ push(rax); |
| 668 } else { | 668 } else { |
| 669 Visit(left); | 669 Visit(left); |
| 670 ASSERT(left->location().is_value()); | 670 ASSERT(left->location().is_value()); |
| 671 switch (destination.type()) { | 671 switch (destination.type()) { |
| 672 case Location::UNINITIALIZED: | 672 case Location::kUninitialized: |
| 673 UNREACHABLE(); | 673 UNREACHABLE(); |
| 674 case Location::EFFECT: | 674 case Location::kEffect: |
| 675 // Pop the left-hand value into rax because we will not need it as the | 675 // Pop the left-hand value into rax because we will not need it as the |
| 676 // final result. | 676 // final result. |
| 677 __ pop(rax); | 677 __ pop(rax); |
| 678 break; | 678 break; |
| 679 case Location::VALUE: | 679 case Location::kValue: |
| 680 // Copy the left-hand value into rax because we may need it as the | 680 // Copy the left-hand value into rax because we may need it as the |
| 681 // final result. | 681 // final result. |
| 682 __ movq(rax, Operand(rsp, 0)); | 682 __ movq(rax, Operand(rsp, 0)); |
| 683 break; | 683 break; |
| 684 } | 684 } |
| 685 } | 685 } |
| 686 // The left-hand value is in rax. It is also on the stack iff the | 686 // The left-hand value is in rax. It is also on the stack iff the |
| 687 // destination location is temporary. | 687 // destination location is temporary. |
| 688 | 688 |
| 689 // Perform fast checks assumed by the stub. | 689 // Perform fast checks assumed by the stub. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 706 __ CallStub(&stub); | 706 __ CallStub(&stub); |
| 707 __ testq(rax, rax); // The stub returns nonzero for true. | 707 __ testq(rax, rax); // The stub returns nonzero for true. |
| 708 __ j(not_zero, &done); | 708 __ j(not_zero, &done); |
| 709 | 709 |
| 710 __ bind(&eval_right); | 710 __ bind(&eval_right); |
| 711 // Discard the left-hand value if present on the stack. | 711 // Discard the left-hand value if present on the stack. |
| 712 if (destination.is_value()) { | 712 if (destination.is_value()) { |
| 713 __ addq(rsp, Immediate(kPointerSize)); | 713 __ addq(rsp, Immediate(kPointerSize)); |
| 714 } | 714 } |
| 715 // Save or discard the right-hand value as needed. | 715 // Save or discard the right-hand value as needed. |
| 716 if (right->AsLiteral() != NULL) { | 716 Visit(right); |
| 717 Move(destination, right->AsLiteral()); | 717 ASSERT_EQ(destination.type(), right->location().type()); |
| 718 } else { | |
| 719 Visit(right); | |
| 720 Move(destination, right->location()); | |
| 721 } | |
| 722 | 718 |
| 723 __ bind(&done); | 719 __ bind(&done); |
| 724 } | 720 } |
| 725 | 721 |
| 726 | 722 |
| 727 } } // namespace v8::internal | 723 } } // namespace v8::internal |
| OLD | NEW |