| 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 17 matching lines...) Expand all  Loading... | 
| 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), | 33           Linkage::GetInterpreterDispatchDescriptor(zone), | 
| 34           MachineType::PointerRepresentation(), | 34           MachineType::PointerRepresentation(), | 
| 35           InstructionSelector::SupportedMachineOperatorFlags())), | 35           InstructionSelector::SupportedMachineOperatorFlags())), | 
| 36       accumulator_( | 36       accumulator_( | 
| 37           raw_assembler_->Parameter(Linkage::kInterpreterAccumulatorParameter)), | 37           raw_assembler_->Parameter(Linkage::kInterpreterAccumulatorParameter)), | 
|  | 38       bytecode_offset_(raw_assembler_->Parameter( | 
|  | 39           Linkage::kInterpreterBytecodeOffsetParameter)), | 
| 38       context_( | 40       context_( | 
| 39           raw_assembler_->Parameter(Linkage::kInterpreterContextParameter)), | 41           raw_assembler_->Parameter(Linkage::kInterpreterContextParameter)), | 
| 40       code_generated_(false) {} | 42       code_generated_(false) {} | 
| 41 | 43 | 
| 42 | 44 | 
| 43 InterpreterAssembler::~InterpreterAssembler() {} | 45 InterpreterAssembler::~InterpreterAssembler() {} | 
| 44 | 46 | 
| 45 | 47 | 
| 46 Handle<Code> InterpreterAssembler::GenerateCode() { | 48 Handle<Code> InterpreterAssembler::GenerateCode() { | 
| 47   DCHECK(!code_generated_); | 49   DCHECK(!code_generated_); | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
| 73 | 75 | 
| 74 void InterpreterAssembler::SetAccumulator(Node* value) { accumulator_ = value; } | 76 void InterpreterAssembler::SetAccumulator(Node* value) { accumulator_ = value; } | 
| 75 | 77 | 
| 76 | 78 | 
| 77 Node* InterpreterAssembler::GetContext() { return context_; } | 79 Node* InterpreterAssembler::GetContext() { return context_; } | 
| 78 | 80 | 
| 79 | 81 | 
| 80 void InterpreterAssembler::SetContext(Node* value) { context_ = value; } | 82 void InterpreterAssembler::SetContext(Node* value) { context_ = value; } | 
| 81 | 83 | 
| 82 | 84 | 
|  | 85 Node* InterpreterAssembler::BytecodeOffset() { return bytecode_offset_; } | 
|  | 86 | 
|  | 87 | 
| 83 Node* InterpreterAssembler::RegisterFileRawPointer() { | 88 Node* InterpreterAssembler::RegisterFileRawPointer() { | 
| 84   return raw_assembler_->Parameter(Linkage::kInterpreterRegisterFileParameter); | 89   return raw_assembler_->Parameter(Linkage::kInterpreterRegisterFileParameter); | 
| 85 } | 90 } | 
| 86 | 91 | 
| 87 | 92 | 
| 88 Node* InterpreterAssembler::BytecodeArrayTaggedPointer() { | 93 Node* InterpreterAssembler::BytecodeArrayTaggedPointer() { | 
| 89   return raw_assembler_->Parameter(Linkage::kInterpreterBytecodeArrayParameter); | 94   return raw_assembler_->Parameter(Linkage::kInterpreterBytecodeArrayParameter); | 
| 90 } | 95 } | 
| 91 | 96 | 
| 92 | 97 | 
| 93 Node* InterpreterAssembler::BytecodeOffset() { |  | 
| 94   return raw_assembler_->Parameter( |  | 
| 95       Linkage::kInterpreterBytecodeOffsetParameter); |  | 
| 96 } |  | 
| 97 |  | 
| 98 |  | 
| 99 Node* InterpreterAssembler::DispatchTableRawPointer() { | 98 Node* InterpreterAssembler::DispatchTableRawPointer() { | 
| 100   return raw_assembler_->Parameter(Linkage::kInterpreterDispatchTableParameter); | 99   return raw_assembler_->Parameter(Linkage::kInterpreterDispatchTableParameter); | 
| 101 } | 100 } | 
| 102 | 101 | 
| 103 | 102 | 
|  | 103 Node* InterpreterAssembler::RegisterLocation(Node* reg_index) { | 
|  | 104   return IntPtrAdd(RegisterFileRawPointer(), RegisterFrameOffset(reg_index)); | 
|  | 105 } | 
|  | 106 | 
|  | 107 | 
|  | 108 Node* InterpreterAssembler::LoadRegister(int offset) { | 
|  | 109   return raw_assembler_->Load(MachineType::AnyTagged(), | 
|  | 110                               RegisterFileRawPointer(), Int32Constant(offset)); | 
|  | 111 } | 
|  | 112 | 
|  | 113 | 
|  | 114 Node* InterpreterAssembler::LoadRegister(interpreter::Register reg) { | 
|  | 115   return LoadRegister(reg.ToOperand() << kPointerSizeLog2); | 
|  | 116 } | 
|  | 117 | 
|  | 118 | 
| 104 Node* InterpreterAssembler::RegisterFrameOffset(Node* index) { | 119 Node* InterpreterAssembler::RegisterFrameOffset(Node* index) { | 
| 105   return WordShl(index, kPointerSizeLog2); | 120   return WordShl(index, kPointerSizeLog2); | 
| 106 } | 121 } | 
| 107 | 122 | 
| 108 | 123 | 
| 109 Node* InterpreterAssembler::RegisterLocation(Node* reg_index) { |  | 
| 110   return IntPtrAdd(RegisterFileRawPointer(), RegisterFrameOffset(reg_index)); |  | 
| 111 } |  | 
| 112 |  | 
| 113 |  | 
| 114 Node* InterpreterAssembler::LoadRegister(interpreter::Register reg) { |  | 
| 115   return raw_assembler_->Load( |  | 
| 116       MachineType::AnyTagged(), RegisterFileRawPointer(), |  | 
| 117       RegisterFrameOffset(Int32Constant(reg.ToOperand()))); |  | 
| 118 } |  | 
| 119 |  | 
| 120 |  | 
| 121 Node* InterpreterAssembler::LoadRegister(Node* reg_index) { | 124 Node* InterpreterAssembler::LoadRegister(Node* reg_index) { | 
| 122   return raw_assembler_->Load(MachineType::AnyTagged(), | 125   return raw_assembler_->Load(MachineType::AnyTagged(), | 
| 123                               RegisterFileRawPointer(), | 126                               RegisterFileRawPointer(), | 
| 124                               RegisterFrameOffset(reg_index)); | 127                               RegisterFrameOffset(reg_index)); | 
| 125 } | 128 } | 
| 126 | 129 | 
| 127 | 130 | 
|  | 131 Node* InterpreterAssembler::StoreRegister(Node* value, int offset) { | 
|  | 132   return raw_assembler_->Store(MachineRepresentation::kTagged, | 
|  | 133                                RegisterFileRawPointer(), Int32Constant(offset), | 
|  | 134                                value, kNoWriteBarrier); | 
|  | 135 } | 
|  | 136 | 
|  | 137 | 
|  | 138 Node* InterpreterAssembler::StoreRegister(Node* value, | 
|  | 139                                           interpreter::Register reg) { | 
|  | 140   return StoreRegister(value, reg.ToOperand() << kPointerSizeLog2); | 
|  | 141 } | 
|  | 142 | 
|  | 143 | 
| 128 Node* InterpreterAssembler::StoreRegister(Node* value, Node* reg_index) { | 144 Node* InterpreterAssembler::StoreRegister(Node* value, Node* reg_index) { | 
| 129   return raw_assembler_->Store( | 145   return raw_assembler_->Store( | 
| 130       MachineRepresentation::kTagged, RegisterFileRawPointer(), | 146       MachineRepresentation::kTagged, RegisterFileRawPointer(), | 
| 131       RegisterFrameOffset(reg_index), value, kNoWriteBarrier); | 147       RegisterFrameOffset(reg_index), value, kNoWriteBarrier); | 
| 132 } | 148 } | 
| 133 | 149 | 
| 134 | 150 | 
| 135 Node* InterpreterAssembler::BytecodeOperand(int operand_index) { | 151 Node* InterpreterAssembler::BytecodeOperand(int operand_index) { | 
| 136   DCHECK_LT(operand_index, interpreter::Bytecodes::NumberOfOperands(bytecode_)); | 152   DCHECK_LT(operand_index, interpreter::Bytecodes::NumberOfOperands(bytecode_)); | 
| 137   DCHECK_EQ(interpreter::OperandSize::kByte, | 153   DCHECK_EQ(interpreter::OperandSize::kByte, | 
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 379   args[0] = arg_count; | 395   args[0] = arg_count; | 
| 380   args[1] = new_target; | 396   args[1] = new_target; | 
| 381   args[2] = constructor; | 397   args[2] = constructor; | 
| 382   args[3] = first_arg; | 398   args[3] = first_arg; | 
| 383   args[4] = GetContext(); | 399   args[4] = GetContext(); | 
| 384 | 400 | 
| 385   return CallN(descriptor, code_target, args); | 401   return CallN(descriptor, code_target, args); | 
| 386 } | 402 } | 
| 387 | 403 | 
| 388 | 404 | 
|  | 405 void InterpreterAssembler::CallPrologue() { | 
|  | 406   StoreRegister(SmiTag(bytecode_offset_), | 
|  | 407                 InterpreterFrameConstants::kBytecodeOffsetFromRegisterPointer); | 
|  | 408 } | 
|  | 409 | 
|  | 410 | 
|  | 411 void InterpreterAssembler::CallEpilogue() { | 
|  | 412   // Restore the bytecode offset from the stack frame. | 
|  | 413   bytecode_offset_ = SmiUntag(LoadRegister( | 
|  | 414       InterpreterFrameConstants::kBytecodeOffsetFromRegisterPointer)); | 
|  | 415 } | 
|  | 416 | 
|  | 417 | 
| 389 Node* InterpreterAssembler::CallN(CallDescriptor* descriptor, Node* code_target, | 418 Node* InterpreterAssembler::CallN(CallDescriptor* descriptor, Node* code_target, | 
| 390                                   Node** args) { | 419                                   Node** args) { | 
|  | 420   CallPrologue(); | 
|  | 421 | 
| 391   Node* stack_pointer_before_call = nullptr; | 422   Node* stack_pointer_before_call = nullptr; | 
| 392   if (FLAG_debug_code) { | 423   if (FLAG_debug_code) { | 
| 393     stack_pointer_before_call = raw_assembler_->LoadStackPointer(); | 424     stack_pointer_before_call = raw_assembler_->LoadStackPointer(); | 
| 394   } | 425   } | 
| 395   Node* return_val = raw_assembler_->CallN(descriptor, code_target, args); | 426   Node* return_val = raw_assembler_->CallN(descriptor, code_target, args); | 
| 396   if (FLAG_debug_code) { | 427   if (FLAG_debug_code) { | 
| 397     Node* stack_pointer_after_call = raw_assembler_->LoadStackPointer(); | 428     Node* stack_pointer_after_call = raw_assembler_->LoadStackPointer(); | 
| 398     AbortIfWordNotEqual(stack_pointer_before_call, stack_pointer_after_call, | 429     AbortIfWordNotEqual(stack_pointer_before_call, stack_pointer_after_call, | 
| 399                         kUnexpectedStackPointer); | 430                         kUnexpectedStackPointer); | 
| 400   } | 431   } | 
|  | 432 | 
|  | 433   CallEpilogue(); | 
| 401   return return_val; | 434   return return_val; | 
| 402 } | 435 } | 
| 403 | 436 | 
| 404 | 437 | 
| 405 Node* InterpreterAssembler::CallJS(Node* function, Node* first_arg, | 438 Node* InterpreterAssembler::CallJS(Node* function, Node* first_arg, | 
| 406                                    Node* arg_count) { | 439                                    Node* arg_count) { | 
| 407   Callable callable = CodeFactory::InterpreterPushArgsAndCall(isolate()); | 440   Callable callable = CodeFactory::InterpreterPushArgsAndCall(isolate()); | 
| 408   CallDescriptor* descriptor = Linkage::GetStubCallDescriptor( | 441   CallDescriptor* descriptor = Linkage::GetStubCallDescriptor( | 
| 409       isolate(), zone(), callable.descriptor(), 0, CallDescriptor::kNoFlags); | 442       isolate(), zone(), callable.descriptor(), 0, CallDescriptor::kNoFlags); | 
| 410 | 443 | 
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 490   args[1] = first_arg; | 523   args[1] = first_arg; | 
| 491   args[2] = function_entry; | 524   args[2] = function_entry; | 
| 492   args[3] = GetContext(); | 525   args[3] = GetContext(); | 
| 493 | 526 | 
| 494   return CallN(descriptor, code_target, args); | 527   return CallN(descriptor, code_target, args); | 
| 495 } | 528 } | 
| 496 | 529 | 
| 497 | 530 | 
| 498 Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id, | 531 Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id, | 
| 499                                         Node* arg1) { | 532                                         Node* arg1) { | 
| 500   return raw_assembler_->CallRuntime1(function_id, arg1, GetContext()); | 533   CallPrologue(); | 
|  | 534   Node* return_val = | 
|  | 535       raw_assembler_->CallRuntime1(function_id, arg1, GetContext()); | 
|  | 536   CallEpilogue(); | 
|  | 537   return return_val; | 
| 501 } | 538 } | 
| 502 | 539 | 
| 503 | 540 | 
| 504 Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id, | 541 Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id, | 
| 505                                         Node* arg1, Node* arg2) { | 542                                         Node* arg1, Node* arg2) { | 
| 506   return raw_assembler_->CallRuntime2(function_id, arg1, arg2, GetContext()); | 543   CallPrologue(); | 
|  | 544   Node* return_val = | 
|  | 545       raw_assembler_->CallRuntime2(function_id, arg1, arg2, GetContext()); | 
|  | 546   CallEpilogue(); | 
|  | 547   return return_val; | 
| 507 } | 548 } | 
| 508 | 549 | 
| 509 | 550 | 
| 510 Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id, | 551 Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id, | 
| 511                                         Node* arg1, Node* arg2, Node* arg3, | 552                                         Node* arg1, Node* arg2, Node* arg3, | 
| 512                                         Node* arg4) { | 553                                         Node* arg4) { | 
| 513   return raw_assembler_->CallRuntime4(function_id, arg1, arg2, arg3, arg4, | 554   CallPrologue(); | 
| 514                                       GetContext()); | 555   Node* return_val = raw_assembler_->CallRuntime4(function_id, arg1, arg2, arg3, | 
|  | 556                                                   arg4, GetContext()); | 
|  | 557   CallEpilogue(); | 
|  | 558   return return_val; | 
| 515 } | 559 } | 
| 516 | 560 | 
| 517 | 561 | 
| 518 void InterpreterAssembler::Return() { | 562 void InterpreterAssembler::Return() { | 
| 519   Node* exit_trampoline_code_object = | 563   Node* exit_trampoline_code_object = | 
| 520       HeapConstant(isolate()->builtins()->InterpreterExitTrampoline()); | 564       HeapConstant(isolate()->builtins()->InterpreterExitTrampoline()); | 
| 521   // If the order of the parameters you need to change the call signature below. | 565   // If the order of the parameters you need to change the call signature below. | 
| 522   STATIC_ASSERT(0 == Linkage::kInterpreterAccumulatorParameter); | 566   STATIC_ASSERT(0 == Linkage::kInterpreterAccumulatorParameter); | 
| 523   STATIC_ASSERT(1 == Linkage::kInterpreterRegisterFileParameter); | 567   STATIC_ASSERT(1 == Linkage::kInterpreterRegisterFileParameter); | 
| 524   STATIC_ASSERT(2 == Linkage::kInterpreterBytecodeOffsetParameter); | 568   STATIC_ASSERT(2 == Linkage::kInterpreterBytecodeOffsetParameter); | 
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 588                    new_bytecode_offset, | 632                    new_bytecode_offset, | 
| 589                    BytecodeArrayTaggedPointer(), | 633                    BytecodeArrayTaggedPointer(), | 
| 590                    DispatchTableRawPointer(), | 634                    DispatchTableRawPointer(), | 
| 591                    GetContext() }; | 635                    GetContext() }; | 
| 592   raw_assembler_->TailCallN(call_descriptor(), target_code_object, args); | 636   raw_assembler_->TailCallN(call_descriptor(), target_code_object, args); | 
| 593 } | 637 } | 
| 594 | 638 | 
| 595 | 639 | 
| 596 void InterpreterAssembler::Abort(BailoutReason bailout_reason) { | 640 void InterpreterAssembler::Abort(BailoutReason bailout_reason) { | 
| 597   Node* abort_id = SmiTag(Int32Constant(bailout_reason)); | 641   Node* abort_id = SmiTag(Int32Constant(bailout_reason)); | 
| 598   CallRuntime(Runtime::kAbort, abort_id); | 642   Node* ret_value = CallRuntime(Runtime::kAbort, abort_id); | 
| 599   Return(); | 643   // Unreached, but keeps turbofan happy. | 
|  | 644   raw_assembler_->Return(ret_value); | 
| 600 } | 645 } | 
| 601 | 646 | 
| 602 | 647 | 
| 603 void InterpreterAssembler::AbortIfWordNotEqual(Node* lhs, Node* rhs, | 648 void InterpreterAssembler::AbortIfWordNotEqual(Node* lhs, Node* rhs, | 
| 604                                                BailoutReason bailout_reason) { | 649                                                BailoutReason bailout_reason) { | 
| 605   RawMachineLabel match, no_match; | 650   RawMachineLabel match, no_match; | 
| 606   Node* condition = raw_assembler_->WordEqual(lhs, rhs); | 651   Node* condition = raw_assembler_->WordEqual(lhs, rhs); | 
| 607   raw_assembler_->Branch(condition, &match, &no_match); | 652   raw_assembler_->Branch(condition, &match, &no_match); | 
| 608   raw_assembler_->Bind(&no_match); | 653   raw_assembler_->Bind(&no_match); | 
| 609   Abort(bailout_reason); | 654   Abort(bailout_reason); | 
| (...skipping 26 matching lines...) Expand all  Loading... | 
| 636   return raw_assembler_->call_descriptor(); | 681   return raw_assembler_->call_descriptor(); | 
| 637 } | 682 } | 
| 638 | 683 | 
| 639 | 684 | 
| 640 Zone* InterpreterAssembler::zone() { return raw_assembler_->zone(); } | 685 Zone* InterpreterAssembler::zone() { return raw_assembler_->zone(); } | 
| 641 | 686 | 
| 642 | 687 | 
| 643 }  // namespace compiler | 688 }  // namespace compiler | 
| 644 }  // namespace internal | 689 }  // namespace internal | 
| 645 }  // namespace v8 | 690 }  // namespace v8 | 
| OLD | NEW | 
|---|