| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 for (int i = 0; i < num_parameters; i++) { | 109 for (int i = 0; i < num_parameters; i++) { |
| 110 Slot* slot = scope()->parameter(i)->AsSlot(); | 110 Slot* slot = scope()->parameter(i)->AsSlot(); |
| 111 if (slot != NULL && slot->type() == Slot::CONTEXT) { | 111 if (slot != NULL && slot->type() == Slot::CONTEXT) { |
| 112 int parameter_offset = StandardFrameConstants::kCallerSPOffset + | 112 int parameter_offset = StandardFrameConstants::kCallerSPOffset + |
| 113 (num_parameters - 1 - i) * kPointerSize; | 113 (num_parameters - 1 - i) * kPointerSize; |
| 114 // Load parameter from stack. | 114 // Load parameter from stack. |
| 115 __ movq(rax, Operand(rbp, parameter_offset)); | 115 __ movq(rax, Operand(rbp, parameter_offset)); |
| 116 // Store it in the context. | 116 // Store it in the context. |
| 117 int context_offset = Context::SlotOffset(slot->index()); | 117 int context_offset = Context::SlotOffset(slot->index()); |
| 118 __ movq(Operand(rsi, context_offset), rax); | 118 __ movq(Operand(rsi, context_offset), rax); |
| 119 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
| 119 // Update the write barrier. This clobbers all involved | 120 // Update the write barrier. This clobbers all involved |
| 120 // registers, so we have use a third register to avoid | 121 // registers, so we have use a third register to avoid |
| 121 // clobbering rsi. | 122 // clobbering rsi. |
| 122 __ movq(rcx, rsi); | 123 __ movq(rcx, rsi); |
| 123 __ RecordWrite(rcx, context_offset, rax, rbx); | 124 __ RecordWrite(rcx, context_offset, rax, rbx); |
| 125 #endif |
| 124 } | 126 } |
| 125 } | 127 } |
| 126 } | 128 } |
| 127 | 129 |
| 128 // Possibly allocate an arguments object. | 130 // Possibly allocate an arguments object. |
| 129 Variable* arguments = scope()->arguments(); | 131 Variable* arguments = scope()->arguments(); |
| 130 if (arguments != NULL) { | 132 if (arguments != NULL) { |
| 131 // Arguments object must be allocated after the context object, in | 133 // Arguments object must be allocated after the context object, in |
| 132 // case the "arguments" or ".arguments" variables are in the context. | 134 // case the "arguments" or ".arguments" variables are in the context. |
| 133 Comment cmnt(masm_, "[ Allocate arguments object"); | 135 Comment cmnt(masm_, "[ Allocate arguments object"); |
| (...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 | 533 |
| 532 | 534 |
| 533 void FullCodeGenerator::Move(Slot* dst, | 535 void FullCodeGenerator::Move(Slot* dst, |
| 534 Register src, | 536 Register src, |
| 535 Register scratch1, | 537 Register scratch1, |
| 536 Register scratch2) { | 538 Register scratch2) { |
| 537 ASSERT(dst->type() != Slot::LOOKUP); // Not yet implemented. | 539 ASSERT(dst->type() != Slot::LOOKUP); // Not yet implemented. |
| 538 ASSERT(!scratch1.is(src) && !scratch2.is(src)); | 540 ASSERT(!scratch1.is(src) && !scratch2.is(src)); |
| 539 MemOperand location = EmitSlotSearch(dst, scratch1); | 541 MemOperand location = EmitSlotSearch(dst, scratch1); |
| 540 __ movq(location, src); | 542 __ movq(location, src); |
| 543 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
| 541 // Emit the write barrier code if the location is in the heap. | 544 // Emit the write barrier code if the location is in the heap. |
| 542 if (dst->type() == Slot::CONTEXT) { | 545 if (dst->type() == Slot::CONTEXT) { |
| 543 int offset = FixedArray::kHeaderSize + dst->index() * kPointerSize; | 546 int offset = FixedArray::kHeaderSize + dst->index() * kPointerSize; |
| 544 __ RecordWrite(scratch1, offset, src, scratch2); | 547 __ RecordWrite(scratch1, offset, src, scratch2); |
| 545 } | 548 } |
| 549 #endif |
| 546 } | 550 } |
| 547 | 551 |
| 548 | 552 |
| 549 void FullCodeGenerator::PrepareForBailoutBeforeSplit(State state, | 553 void FullCodeGenerator::PrepareForBailoutBeforeSplit(State state, |
| 550 bool should_normalize, | 554 bool should_normalize, |
| 551 Label* if_true, | 555 Label* if_true, |
| 552 Label* if_false) { | 556 Label* if_false) { |
| 553 } | 557 } |
| 554 | 558 |
| 555 | 559 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 586 __ cmpq(rbx, rsi); | 590 __ cmpq(rbx, rsi); |
| 587 __ Check(equal, "Unexpected declaration in current context."); | 591 __ Check(equal, "Unexpected declaration in current context."); |
| 588 } | 592 } |
| 589 if (mode == Variable::CONST) { | 593 if (mode == Variable::CONST) { |
| 590 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex); | 594 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex); |
| 591 __ movq(ContextOperand(rsi, slot->index()), kScratchRegister); | 595 __ movq(ContextOperand(rsi, slot->index()), kScratchRegister); |
| 592 // No write barrier since the hole value is in old space. | 596 // No write barrier since the hole value is in old space. |
| 593 } else if (function != NULL) { | 597 } else if (function != NULL) { |
| 594 VisitForAccumulatorValue(function); | 598 VisitForAccumulatorValue(function); |
| 595 __ movq(ContextOperand(rsi, slot->index()), result_register()); | 599 __ movq(ContextOperand(rsi, slot->index()), result_register()); |
| 600 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
| 596 int offset = Context::SlotOffset(slot->index()); | 601 int offset = Context::SlotOffset(slot->index()); |
| 597 __ movq(rbx, rsi); | 602 __ movq(rbx, rsi); |
| 598 __ RecordWrite(rbx, offset, result_register(), rcx); | 603 __ RecordWrite(rbx, offset, result_register(), rcx); |
| 604 #endif |
| 599 } | 605 } |
| 600 break; | 606 break; |
| 601 | 607 |
| 602 case Slot::LOOKUP: { | 608 case Slot::LOOKUP: { |
| 603 __ push(rsi); | 609 __ push(rsi); |
| 604 __ Push(variable->name()); | 610 __ Push(variable->name()); |
| 605 // Declaration nodes are always introduced in one of two modes. | 611 // Declaration nodes are always introduced in one of two modes. |
| 606 ASSERT(mode == Variable::VAR || mode == Variable::CONST); | 612 ASSERT(mode == Variable::VAR || mode == Variable::CONST); |
| 607 PropertyAttributes attr = (mode == Variable::VAR) ? NONE : READ_ONLY; | 613 PropertyAttributes attr = (mode == Variable::VAR) ? NONE : READ_ONLY; |
| 608 __ Push(Smi::FromInt(attr)); | 614 __ Push(Smi::FromInt(attr)); |
| (...skipping 688 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1297 result_saved = true; | 1303 result_saved = true; |
| 1298 } | 1304 } |
| 1299 VisitForAccumulatorValue(subexpr); | 1305 VisitForAccumulatorValue(subexpr); |
| 1300 | 1306 |
| 1301 // Store the subexpression value in the array's elements. | 1307 // Store the subexpression value in the array's elements. |
| 1302 __ movq(rbx, Operand(rsp, 0)); // Copy of array literal. | 1308 __ movq(rbx, Operand(rsp, 0)); // Copy of array literal. |
| 1303 __ movq(rbx, FieldOperand(rbx, JSObject::kElementsOffset)); | 1309 __ movq(rbx, FieldOperand(rbx, JSObject::kElementsOffset)); |
| 1304 int offset = FixedArray::kHeaderSize + (i * kPointerSize); | 1310 int offset = FixedArray::kHeaderSize + (i * kPointerSize); |
| 1305 __ movq(FieldOperand(rbx, offset), result_register()); | 1311 __ movq(FieldOperand(rbx, offset), result_register()); |
| 1306 | 1312 |
| 1313 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
| 1307 // Update the write barrier for the array store. | 1314 // Update the write barrier for the array store. |
| 1308 __ RecordWrite(rbx, offset, result_register(), rcx); | 1315 __ RecordWrite(rbx, offset, result_register(), rcx); |
| 1316 #endif |
| 1309 } | 1317 } |
| 1310 | 1318 |
| 1311 if (result_saved) { | 1319 if (result_saved) { |
| 1312 context()->PlugTOS(); | 1320 context()->PlugTOS(); |
| 1313 } else { | 1321 } else { |
| 1314 context()->Plug(rax); | 1322 context()->Plug(rax); |
| 1315 } | 1323 } |
| 1316 } | 1324 } |
| 1317 | 1325 |
| 1318 | 1326 |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1614 case Slot::CONTEXT: { | 1622 case Slot::CONTEXT: { |
| 1615 MemOperand target = EmitSlotSearch(slot, rcx); | 1623 MemOperand target = EmitSlotSearch(slot, rcx); |
| 1616 if (op == Token::INIT_CONST) { | 1624 if (op == Token::INIT_CONST) { |
| 1617 // Detect const reinitialization by checking for the hole value. | 1625 // Detect const reinitialization by checking for the hole value. |
| 1618 __ movq(rdx, target); | 1626 __ movq(rdx, target); |
| 1619 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); | 1627 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); |
| 1620 __ j(not_equal, &done); | 1628 __ j(not_equal, &done); |
| 1621 } | 1629 } |
| 1622 // Perform the assignment and issue the write barrier. | 1630 // Perform the assignment and issue the write barrier. |
| 1623 __ movq(target, rax); | 1631 __ movq(target, rax); |
| 1632 |
| 1633 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
| 1624 // The value of the assignment is in rax. RecordWrite clobbers its | 1634 // The value of the assignment is in rax. RecordWrite clobbers its |
| 1625 // register arguments. | 1635 // register arguments. |
| 1626 __ movq(rdx, rax); | 1636 __ movq(rdx, rax); |
| 1627 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; | 1637 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; |
| 1628 __ RecordWrite(rcx, offset, rdx, rbx); | 1638 __ RecordWrite(rcx, offset, rdx, rbx); |
| 1639 #endif |
| 1629 break; | 1640 break; |
| 1630 } | 1641 } |
| 1631 | 1642 |
| 1632 case Slot::LOOKUP: | 1643 case Slot::LOOKUP: |
| 1633 // Call the runtime for the assignment. The runtime will ignore | 1644 // Call the runtime for the assignment. The runtime will ignore |
| 1634 // const reinitialization. | 1645 // const reinitialization. |
| 1635 __ push(rax); // Value. | 1646 __ push(rax); // Value. |
| 1636 __ push(rsi); // Context. | 1647 __ push(rsi); // Context. |
| 1637 __ Push(var->name()); | 1648 __ Push(var->name()); |
| 1638 if (op == Token::INIT_CONST) { | 1649 if (op == Token::INIT_CONST) { |
| (...skipping 824 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2463 Label done; | 2474 Label done; |
| 2464 // If the object is a smi, return the value. | 2475 // If the object is a smi, return the value. |
| 2465 __ JumpIfSmi(rbx, &done); | 2476 __ JumpIfSmi(rbx, &done); |
| 2466 | 2477 |
| 2467 // If the object is not a value type, return the value. | 2478 // If the object is not a value type, return the value. |
| 2468 __ CmpObjectType(rbx, JS_VALUE_TYPE, rcx); | 2479 __ CmpObjectType(rbx, JS_VALUE_TYPE, rcx); |
| 2469 __ j(not_equal, &done); | 2480 __ j(not_equal, &done); |
| 2470 | 2481 |
| 2471 // Store the value. | 2482 // Store the value. |
| 2472 __ movq(FieldOperand(rbx, JSValue::kValueOffset), rax); | 2483 __ movq(FieldOperand(rbx, JSValue::kValueOffset), rax); |
| 2484 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
| 2473 // Update the write barrier. Save the value as it will be | 2485 // Update the write barrier. Save the value as it will be |
| 2474 // overwritten by the write barrier code and is needed afterward. | 2486 // overwritten by the write barrier code and is needed afterward. |
| 2475 __ movq(rdx, rax); | 2487 __ movq(rdx, rax); |
| 2476 __ RecordWrite(rbx, JSValue::kValueOffset, rdx, rcx); | 2488 __ RecordWrite(rbx, JSValue::kValueOffset, rdx, rcx); |
| 2489 #endif |
| 2477 | 2490 |
| 2478 __ bind(&done); | 2491 __ bind(&done); |
| 2479 context()->Plug(rax); | 2492 context()->Plug(rax); |
| 2480 } | 2493 } |
| 2481 | 2494 |
| 2482 | 2495 |
| 2483 void FullCodeGenerator::EmitNumberToString(ZoneList<Expression*>* args) { | 2496 void FullCodeGenerator::EmitNumberToString(ZoneList<Expression*>* args) { |
| 2484 ASSERT_EQ(args->length(), 1); | 2497 ASSERT_EQ(args->length(), 1); |
| 2485 | 2498 |
| 2486 // Load the argument on the stack and call the stub. | 2499 // Load the argument on the stack and call the stub. |
| (...skipping 1029 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3516 __ ret(0); | 3529 __ ret(0); |
| 3517 } | 3530 } |
| 3518 | 3531 |
| 3519 | 3532 |
| 3520 #undef __ | 3533 #undef __ |
| 3521 | 3534 |
| 3522 | 3535 |
| 3523 } } // namespace v8::internal | 3536 } } // namespace v8::internal |
| 3524 | 3537 |
| 3525 #endif // V8_TARGET_ARCH_X64 | 3538 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |