| OLD | NEW | 
|---|
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "src/compiler/interpreter-assembler.h" | 5 #include "src/compiler/interpreter-assembler.h" | 
| 6 | 6 | 
| 7 #include <ostream> | 7 #include <ostream> | 
| 8 | 8 | 
| 9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" | 
| 10 #include "src/compiler/graph.h" | 10 #include "src/compiler/graph.h" | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 27 | 27 | 
| 28 InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone, | 28 InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone, | 
| 29                                            interpreter::Bytecode bytecode) | 29                                            interpreter::Bytecode bytecode) | 
| 30     : bytecode_(bytecode), | 30     : bytecode_(bytecode), | 
| 31       raw_assembler_(new RawMachineAssembler( | 31       raw_assembler_(new RawMachineAssembler( | 
| 32           isolate, new (zone) Graph(zone), | 32           isolate, new (zone) Graph(zone), | 
| 33           Linkage::GetInterpreterDispatchDescriptor(zone), kMachPtr, | 33           Linkage::GetInterpreterDispatchDescriptor(zone), kMachPtr, | 
| 34           InstructionSelector::SupportedMachineOperatorFlags())), | 34           InstructionSelector::SupportedMachineOperatorFlags())), | 
| 35       accumulator_( | 35       accumulator_( | 
| 36           raw_assembler_->Parameter(Linkage::kInterpreterAccumulatorParameter)), | 36           raw_assembler_->Parameter(Linkage::kInterpreterAccumulatorParameter)), | 
|  | 37       bytecode_offset_(raw_assembler_->Parameter( | 
|  | 38           Linkage::kInterpreterBytecodeOffsetParameter)), | 
| 37       context_( | 39       context_( | 
| 38           raw_assembler_->Parameter(Linkage::kInterpreterContextParameter)), | 40           raw_assembler_->Parameter(Linkage::kInterpreterContextParameter)), | 
| 39       code_generated_(false) {} | 41       code_generated_(false) {} | 
| 40 | 42 | 
| 41 | 43 | 
| 42 InterpreterAssembler::~InterpreterAssembler() {} | 44 InterpreterAssembler::~InterpreterAssembler() {} | 
| 43 | 45 | 
| 44 | 46 | 
| 45 Handle<Code> InterpreterAssembler::GenerateCode() { | 47 Handle<Code> InterpreterAssembler::GenerateCode() { | 
| 46   DCHECK(!code_generated_); | 48   DCHECK(!code_generated_); | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
| 72 | 74 | 
| 73 void InterpreterAssembler::SetAccumulator(Node* value) { accumulator_ = value; } | 75 void InterpreterAssembler::SetAccumulator(Node* value) { accumulator_ = value; } | 
| 74 | 76 | 
| 75 | 77 | 
| 76 Node* InterpreterAssembler::GetContext() { return context_; } | 78 Node* InterpreterAssembler::GetContext() { return context_; } | 
| 77 | 79 | 
| 78 | 80 | 
| 79 void InterpreterAssembler::SetContext(Node* value) { context_ = value; } | 81 void InterpreterAssembler::SetContext(Node* value) { context_ = value; } | 
| 80 | 82 | 
| 81 | 83 | 
|  | 84 Node* InterpreterAssembler::BytecodeOffset() { return bytecode_offset_; } | 
|  | 85 | 
|  | 86 | 
| 82 Node* InterpreterAssembler::RegisterFileRawPointer() { | 87 Node* InterpreterAssembler::RegisterFileRawPointer() { | 
| 83   return raw_assembler_->Parameter(Linkage::kInterpreterRegisterFileParameter); | 88   return raw_assembler_->Parameter(Linkage::kInterpreterRegisterFileParameter); | 
| 84 } | 89 } | 
| 85 | 90 | 
| 86 | 91 | 
| 87 Node* InterpreterAssembler::BytecodeArrayTaggedPointer() { | 92 Node* InterpreterAssembler::BytecodeArrayTaggedPointer() { | 
| 88   return raw_assembler_->Parameter(Linkage::kInterpreterBytecodeArrayParameter); | 93   return raw_assembler_->Parameter(Linkage::kInterpreterBytecodeArrayParameter); | 
| 89 } | 94 } | 
| 90 | 95 | 
| 91 | 96 | 
| 92 Node* InterpreterAssembler::BytecodeOffset() { |  | 
| 93   return raw_assembler_->Parameter( |  | 
| 94       Linkage::kInterpreterBytecodeOffsetParameter); |  | 
| 95 } |  | 
| 96 |  | 
| 97 |  | 
| 98 Node* InterpreterAssembler::DispatchTableRawPointer() { | 97 Node* InterpreterAssembler::DispatchTableRawPointer() { | 
| 99   return raw_assembler_->Parameter(Linkage::kInterpreterDispatchTableParameter); | 98   return raw_assembler_->Parameter(Linkage::kInterpreterDispatchTableParameter); | 
| 100 } | 99 } | 
| 101 | 100 | 
| 102 | 101 | 
|  | 102 Node* InterpreterAssembler::RegisterLocation(Node* reg_index) { | 
|  | 103   return IntPtrAdd(RegisterFileRawPointer(), RegisterFrameOffset(reg_index)); | 
|  | 104 } | 
|  | 105 | 
|  | 106 | 
|  | 107 Node* InterpreterAssembler::LoadRegister(int offset) { | 
|  | 108   return raw_assembler_->Load(kMachAnyTagged, RegisterFileRawPointer(), | 
|  | 109                               Int32Constant(offset)); | 
|  | 110 } | 
|  | 111 | 
|  | 112 | 
|  | 113 Node* InterpreterAssembler::LoadRegister(interpreter::Register reg) { | 
|  | 114   return LoadRegister(reg.ToOperand() << kPointerSizeLog2); | 
|  | 115 } | 
|  | 116 | 
|  | 117 | 
| 103 Node* InterpreterAssembler::RegisterFrameOffset(Node* index) { | 118 Node* InterpreterAssembler::RegisterFrameOffset(Node* index) { | 
| 104   return WordShl(index, kPointerSizeLog2); | 119   return WordShl(index, kPointerSizeLog2); | 
| 105 } | 120 } | 
| 106 | 121 | 
| 107 | 122 | 
| 108 Node* InterpreterAssembler::RegisterLocation(Node* reg_index) { |  | 
| 109   return IntPtrAdd(RegisterFileRawPointer(), RegisterFrameOffset(reg_index)); |  | 
| 110 } |  | 
| 111 |  | 
| 112 |  | 
| 113 Node* InterpreterAssembler::LoadRegister(interpreter::Register reg) { |  | 
| 114   return raw_assembler_->Load( |  | 
| 115       kMachAnyTagged, RegisterFileRawPointer(), |  | 
| 116       RegisterFrameOffset(Int32Constant(reg.ToOperand()))); |  | 
| 117 } |  | 
| 118 |  | 
| 119 |  | 
| 120 Node* InterpreterAssembler::LoadRegister(Node* reg_index) { | 123 Node* InterpreterAssembler::LoadRegister(Node* reg_index) { | 
| 121   return raw_assembler_->Load(kMachAnyTagged, RegisterFileRawPointer(), | 124   return raw_assembler_->Load(kMachAnyTagged, RegisterFileRawPointer(), | 
| 122                               RegisterFrameOffset(reg_index)); | 125                               RegisterFrameOffset(reg_index)); | 
| 123 } | 126 } | 
| 124 | 127 | 
| 125 | 128 | 
|  | 129 Node* InterpreterAssembler::StoreRegister(Node* value, int offset) { | 
|  | 130   return raw_assembler_->Store(kMachAnyTagged, RegisterFileRawPointer(), | 
|  | 131                                Int32Constant(offset), value, kNoWriteBarrier); | 
|  | 132 } | 
|  | 133 | 
|  | 134 | 
|  | 135 Node* InterpreterAssembler::StoreRegister(Node* value, | 
|  | 136                                           interpreter::Register reg) { | 
|  | 137   return StoreRegister(value, reg.ToOperand() << kPointerSizeLog2); | 
|  | 138 } | 
|  | 139 | 
|  | 140 | 
| 126 Node* InterpreterAssembler::StoreRegister(Node* value, Node* reg_index) { | 141 Node* InterpreterAssembler::StoreRegister(Node* value, Node* reg_index) { | 
| 127   return raw_assembler_->Store(kMachAnyTagged, RegisterFileRawPointer(), | 142   return raw_assembler_->Store(kMachAnyTagged, RegisterFileRawPointer(), | 
| 128                                RegisterFrameOffset(reg_index), value, | 143                                RegisterFrameOffset(reg_index), value, | 
| 129                                kNoWriteBarrier); | 144                                kNoWriteBarrier); | 
| 130 } | 145 } | 
| 131 | 146 | 
| 132 | 147 | 
| 133 Node* InterpreterAssembler::BytecodeOperand(int operand_index) { | 148 Node* InterpreterAssembler::BytecodeOperand(int operand_index) { | 
| 134   DCHECK_LT(operand_index, interpreter::Bytecodes::NumberOfOperands(bytecode_)); | 149   DCHECK_LT(operand_index, interpreter::Bytecodes::NumberOfOperands(bytecode_)); | 
| 135   DCHECK_EQ(interpreter::OperandSize::kByte, | 150   DCHECK_EQ(interpreter::OperandSize::kByte, | 
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 375   args[0] = arg_count; | 390   args[0] = arg_count; | 
| 376   args[1] = new_target; | 391   args[1] = new_target; | 
| 377   args[2] = constructor; | 392   args[2] = constructor; | 
| 378   args[3] = first_arg; | 393   args[3] = first_arg; | 
| 379   args[4] = GetContext(); | 394   args[4] = GetContext(); | 
| 380 | 395 | 
| 381   return CallN(descriptor, code_target, args); | 396   return CallN(descriptor, code_target, args); | 
| 382 } | 397 } | 
| 383 | 398 | 
| 384 | 399 | 
|  | 400 void InterpreterAssembler::CallPrologue() { | 
|  | 401   StoreRegister(SmiTag(bytecode_offset_), | 
|  | 402                 InterpreterFrameConstants::kBytecodeOffsetFromRegisterPointer); | 
|  | 403 } | 
|  | 404 | 
|  | 405 | 
|  | 406 void InterpreterAssembler::CallEpilogue() { | 
|  | 407   // Restore the bytecode offset from the stack frame. | 
|  | 408   bytecode_offset_ = SmiUntag(LoadRegister( | 
|  | 409       InterpreterFrameConstants::kBytecodeOffsetFromRegisterPointer)); | 
|  | 410 } | 
|  | 411 | 
|  | 412 | 
| 385 Node* InterpreterAssembler::CallN(CallDescriptor* descriptor, Node* code_target, | 413 Node* InterpreterAssembler::CallN(CallDescriptor* descriptor, Node* code_target, | 
| 386                                   Node** args) { | 414                                   Node** args) { | 
|  | 415   CallPrologue(); | 
|  | 416 | 
| 387   Node* stack_pointer_before_call = nullptr; | 417   Node* stack_pointer_before_call = nullptr; | 
| 388   if (FLAG_debug_code) { | 418   if (FLAG_debug_code) { | 
| 389     stack_pointer_before_call = raw_assembler_->LoadStackPointer(); | 419     stack_pointer_before_call = raw_assembler_->LoadStackPointer(); | 
| 390   } | 420   } | 
| 391   Node* return_val = raw_assembler_->CallN(descriptor, code_target, args); | 421   Node* return_val = raw_assembler_->CallN(descriptor, code_target, args); | 
| 392   if (FLAG_debug_code) { | 422   if (FLAG_debug_code) { | 
| 393     Node* stack_pointer_after_call = raw_assembler_->LoadStackPointer(); | 423     Node* stack_pointer_after_call = raw_assembler_->LoadStackPointer(); | 
| 394     AbortIfWordNotEqual(stack_pointer_before_call, stack_pointer_after_call, | 424     AbortIfWordNotEqual(stack_pointer_before_call, stack_pointer_after_call, | 
| 395                         kUnexpectedStackPointer); | 425                         kUnexpectedStackPointer); | 
| 396   } | 426   } | 
|  | 427 | 
|  | 428   CallEpilogue(); | 
| 397   return return_val; | 429   return return_val; | 
| 398 } | 430 } | 
| 399 | 431 | 
| 400 | 432 | 
| 401 Node* InterpreterAssembler::CallJS(Node* function, Node* first_arg, | 433 Node* InterpreterAssembler::CallJS(Node* function, Node* first_arg, | 
| 402                                    Node* arg_count) { | 434                                    Node* arg_count) { | 
| 403   Callable callable = CodeFactory::InterpreterPushArgsAndCall(isolate()); | 435   Callable callable = CodeFactory::InterpreterPushArgsAndCall(isolate()); | 
| 404   CallDescriptor* descriptor = Linkage::GetStubCallDescriptor( | 436   CallDescriptor* descriptor = Linkage::GetStubCallDescriptor( | 
| 405       isolate(), zone(), callable.descriptor(), 0, CallDescriptor::kNoFlags); | 437       isolate(), zone(), callable.descriptor(), 0, CallDescriptor::kNoFlags); | 
| 406 | 438 | 
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 485   args[1] = first_arg; | 517   args[1] = first_arg; | 
| 486   args[2] = function_entry; | 518   args[2] = function_entry; | 
| 487   args[3] = GetContext(); | 519   args[3] = GetContext(); | 
| 488 | 520 | 
| 489   return CallN(descriptor, code_target, args); | 521   return CallN(descriptor, code_target, args); | 
| 490 } | 522 } | 
| 491 | 523 | 
| 492 | 524 | 
| 493 Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id, | 525 Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id, | 
| 494                                         Node* arg1) { | 526                                         Node* arg1) { | 
| 495   return raw_assembler_->CallRuntime1(function_id, arg1, GetContext()); | 527   CallPrologue(); | 
|  | 528   Node* return_val = | 
|  | 529       raw_assembler_->CallRuntime1(function_id, arg1, GetContext()); | 
|  | 530   CallEpilogue(); | 
|  | 531   return return_val; | 
| 496 } | 532 } | 
| 497 | 533 | 
| 498 | 534 | 
| 499 Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id, | 535 Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id, | 
| 500                                         Node* arg1, Node* arg2) { | 536                                         Node* arg1, Node* arg2) { | 
| 501   return raw_assembler_->CallRuntime2(function_id, arg1, arg2, GetContext()); | 537   CallPrologue(); | 
|  | 538   Node* return_val = | 
|  | 539       raw_assembler_->CallRuntime2(function_id, arg1, arg2, GetContext()); | 
|  | 540   CallEpilogue(); | 
|  | 541   return return_val; | 
| 502 } | 542 } | 
| 503 | 543 | 
| 504 | 544 | 
| 505 Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id, | 545 Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id, | 
| 506                                         Node* arg1, Node* arg2, Node* arg3, | 546                                         Node* arg1, Node* arg2, Node* arg3, | 
| 507                                         Node* arg4) { | 547                                         Node* arg4) { | 
| 508   return raw_assembler_->CallRuntime4(function_id, arg1, arg2, arg3, arg4, | 548   CallPrologue(); | 
| 509                                       GetContext()); | 549   Node* return_val = raw_assembler_->CallRuntime4(function_id, arg1, arg2, arg3, | 
|  | 550                                                   arg4, GetContext()); | 
|  | 551   CallEpilogue(); | 
|  | 552   return return_val; | 
| 510 } | 553 } | 
| 511 | 554 | 
| 512 | 555 | 
| 513 void InterpreterAssembler::Return() { | 556 void InterpreterAssembler::Return() { | 
| 514   Node* exit_trampoline_code_object = | 557   Node* exit_trampoline_code_object = | 
| 515       HeapConstant(isolate()->builtins()->InterpreterExitTrampoline()); | 558       HeapConstant(isolate()->builtins()->InterpreterExitTrampoline()); | 
| 516   // If the order of the parameters you need to change the call signature below. | 559   // If the order of the parameters you need to change the call signature below. | 
| 517   STATIC_ASSERT(0 == Linkage::kInterpreterAccumulatorParameter); | 560   STATIC_ASSERT(0 == Linkage::kInterpreterAccumulatorParameter); | 
| 518   STATIC_ASSERT(1 == Linkage::kInterpreterRegisterFileParameter); | 561   STATIC_ASSERT(1 == Linkage::kInterpreterRegisterFileParameter); | 
| 519   STATIC_ASSERT(2 == Linkage::kInterpreterBytecodeOffsetParameter); | 562   STATIC_ASSERT(2 == Linkage::kInterpreterBytecodeOffsetParameter); | 
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 583                    new_bytecode_offset, | 626                    new_bytecode_offset, | 
| 584                    BytecodeArrayTaggedPointer(), | 627                    BytecodeArrayTaggedPointer(), | 
| 585                    DispatchTableRawPointer(), | 628                    DispatchTableRawPointer(), | 
| 586                    GetContext() }; | 629                    GetContext() }; | 
| 587   raw_assembler_->TailCallN(call_descriptor(), target_code_object, args); | 630   raw_assembler_->TailCallN(call_descriptor(), target_code_object, args); | 
| 588 } | 631 } | 
| 589 | 632 | 
| 590 | 633 | 
| 591 void InterpreterAssembler::Abort(BailoutReason bailout_reason) { | 634 void InterpreterAssembler::Abort(BailoutReason bailout_reason) { | 
| 592   Node* abort_id = SmiTag(Int32Constant(bailout_reason)); | 635   Node* abort_id = SmiTag(Int32Constant(bailout_reason)); | 
| 593   CallRuntime(Runtime::kAbort, abort_id); | 636   Node* ret_value = CallRuntime(Runtime::kAbort, abort_id); | 
| 594   Return(); | 637   // Unreached, but keeps turbofan happy. | 
|  | 638   raw_assembler_->Return(ret_value); | 
| 595 } | 639 } | 
| 596 | 640 | 
| 597 | 641 | 
| 598 void InterpreterAssembler::AbortIfWordNotEqual(Node* lhs, Node* rhs, | 642 void InterpreterAssembler::AbortIfWordNotEqual(Node* lhs, Node* rhs, | 
| 599                                                BailoutReason bailout_reason) { | 643                                                BailoutReason bailout_reason) { | 
| 600   RawMachineLabel match, no_match; | 644   RawMachineLabel match, no_match; | 
| 601   Node* condition = raw_assembler_->WordEqual(lhs, rhs); | 645   Node* condition = raw_assembler_->WordEqual(lhs, rhs); | 
| 602   raw_assembler_->Branch(condition, &match, &no_match); | 646   raw_assembler_->Branch(condition, &match, &no_match); | 
| 603   raw_assembler_->Bind(&no_match); | 647   raw_assembler_->Bind(&no_match); | 
| 604   Abort(bailout_reason); | 648   Abort(bailout_reason); | 
| (...skipping 26 matching lines...) Expand all  Loading... | 
| 631   return raw_assembler_->call_descriptor(); | 675   return raw_assembler_->call_descriptor(); | 
| 632 } | 676 } | 
| 633 | 677 | 
| 634 | 678 | 
| 635 Zone* InterpreterAssembler::zone() { return raw_assembler_->zone(); } | 679 Zone* InterpreterAssembler::zone() { return raw_assembler_->zone(); } | 
| 636 | 680 | 
| 637 | 681 | 
| 638 }  // namespace compiler | 682 }  // namespace compiler | 
| 639 }  // namespace internal | 683 }  // namespace internal | 
| 640 }  // namespace v8 | 684 }  // namespace v8 | 
| OLD | NEW | 
|---|