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 |