| Index: src/compiler/interpreter-assembler.cc
|
| diff --git a/src/compiler/interpreter-assembler.cc b/src/compiler/interpreter-assembler.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..696ed4ac4e5d9590181279c6b6952c9d480d9283
|
| --- /dev/null
|
| +++ b/src/compiler/interpreter-assembler.cc
|
| @@ -0,0 +1,180 @@
|
| +// Copyright 2015 the V8 project authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "src/compiler/interpreter-assembler.h"
|
| +
|
| +#include <ostream>
|
| +
|
| +#include "src/compiler/graph.h"
|
| +#include "src/compiler/instruction-selector.h"
|
| +#include "src/compiler/linkage.h"
|
| +#include "src/compiler/machine-type.h"
|
| +#include "src/compiler/pipeline.h"
|
| +#include "src/compiler/raw-machine-assembler.h"
|
| +#include "src/compiler/schedule.h"
|
| +#include "src/frames.h"
|
| +#include "src/interpreter/bytecodes.h"
|
| +#include "src/macro-assembler.h"
|
| +#include "src/zone.h"
|
| +
|
| +namespace v8 {
|
| +namespace internal {
|
| +namespace compiler {
|
| +
|
| +
|
| +InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone,
|
| + interpreter::Bytecode bytecode)
|
| + : zone_(zone),
|
| + bytecode_(bytecode),
|
| + raw_assembler_(new RawMachineAssembler(
|
| + isolate, new (zone) Graph(zone),
|
| + Linkage::GetInterpreterDispatchDescriptor(zone), kMachPtr,
|
| + InstructionSelector::SupportedMachineOperatorFlags())),
|
| + code_generated_(false) {}
|
| +
|
| +
|
| +InterpreterAssembler::~InterpreterAssembler() {}
|
| +
|
| +
|
| +Handle<Code> InterpreterAssembler::GenerateCode() {
|
| + DCHECK(!code_generated_);
|
| +
|
| + Schedule* schedule = raw_assembler_->Export();
|
| + // TODO(rmcilroy): use a non-testing code generator.
|
| + Handle<Code> code = Pipeline::GenerateCodeForTesting(
|
| + isolate(), raw_assembler_->call_descriptor(), graph(), schedule);
|
| +
|
| +#ifdef ENABLE_DISASSEMBLER
|
| + if (FLAG_trace_ignition_codegen) {
|
| + OFStream os(stdout);
|
| + code->Disassemble(interpreter::Bytecodes::ToString(bytecode_), os);
|
| + os << std::flush;
|
| + }
|
| +#endif
|
| +
|
| + code_generated_ = true;
|
| + return code;
|
| +}
|
| +
|
| +
|
| +Node* InterpreterAssembler::BytecodePointer() {
|
| + return raw_assembler_->Parameter(Linkage::kInterpreterBytecodeParameter);
|
| +}
|
| +
|
| +
|
| +Node* InterpreterAssembler::DispatchTablePointer() {
|
| + return raw_assembler_->Parameter(Linkage::kInterpreterDispatchTableParameter);
|
| +}
|
| +
|
| +
|
| +Node* InterpreterAssembler::FramePointer() {
|
| + return raw_assembler_->LoadFramePointer();
|
| +}
|
| +
|
| +
|
| +Node* InterpreterAssembler::RegisterFrameOffset(int index) {
|
| + return Int32Constant(kFirstRegsterOffsetFromFp - (index << kPointerSizeLog2));
|
| +}
|
| +
|
| +
|
| +Node* InterpreterAssembler::RegisterFrameOffset(Node* index) {
|
| + return raw_assembler_->Int32Sub(
|
| + Int32Constant(kFirstRegsterOffsetFromFp),
|
| + raw_assembler_->WordShl(index, Int32Constant(kPointerSizeLog2)));
|
| +}
|
| +
|
| +
|
| +Node* InterpreterAssembler::BytecodeArg(int delta) {
|
| + DCHECK_LT(delta, interpreter::Bytecodes::NumberOfArguments(bytecode_));
|
| + return raw_assembler_->Load(kMachUint8, BytecodePointer(),
|
| + Int32Constant(1 + delta));
|
| +}
|
| +
|
| +
|
| +Node* InterpreterAssembler::LoadRegister(int index) {
|
| + return raw_assembler_->Load(kMachPtr, FramePointer(),
|
| + RegisterFrameOffset(index));
|
| +}
|
| +
|
| +
|
| +Node* InterpreterAssembler::LoadRegister(Node* index) {
|
| + return raw_assembler_->Load(kMachPtr, FramePointer(),
|
| + RegisterFrameOffset(index));
|
| +}
|
| +
|
| +
|
| +void InterpreterAssembler::StoreRegister(Node* value, int index) {
|
| + raw_assembler_->Store(kMachPtr, FramePointer(), RegisterFrameOffset(index),
|
| + value);
|
| +}
|
| +
|
| +
|
| +void InterpreterAssembler::StoreRegister(Node* value, Node* index) {
|
| + raw_assembler_->Store(kMachPtr, FramePointer(), RegisterFrameOffset(index),
|
| + value);
|
| +}
|
| +
|
| +
|
| +Node* InterpreterAssembler::Advance(int delta) {
|
| + return raw_assembler_->IntPtrAdd(BytecodePointer(), Int32Constant(delta));
|
| +}
|
| +
|
| +
|
| +void InterpreterAssembler::Dispatch() {
|
| + Node* new_bytecode_pointer = Advance(interpreter::Bytecodes::Size(bytecode_));
|
| + Node* target_bytecode =
|
| + raw_assembler_->Load(kMachUint8, new_bytecode_pointer);
|
| +
|
| + // TODO(rmcilroy): Create a code target dispatch table to avoid conversion
|
| + // from code object on every dispatch.
|
| + Node* target_code_object = raw_assembler_->Load(
|
| + kMachPtr, DispatchTablePointer(),
|
| + raw_assembler_->WordShl(target_bytecode,
|
| + Int32Constant(kPointerSizeLog2)));
|
| +
|
| + // If the order of the parameters you need to change the call signature below.
|
| + DCHECK_EQ(0, Linkage::kInterpreterBytecodeParameter);
|
| + DCHECK_EQ(1, Linkage::kInterpreterDispatchTableParameter);
|
| + Node* tail_call = graph()->NewNode(
|
| + common()->TailCall(Linkage::GetInterpreterDispatchDescriptor(zone_)),
|
| + target_code_object, new_bytecode_pointer, DispatchTablePointer());
|
| + schedule()->AddTailCall(raw_assembler_->CurrentBlock(), tail_call);
|
| +}
|
| +
|
| +
|
| +// RawMachineAssembler delegate helpers:
|
| +Isolate* InterpreterAssembler::isolate() { return raw_assembler_->isolate(); }
|
| +
|
| +
|
| +Graph* InterpreterAssembler::graph() { return raw_assembler_->graph(); }
|
| +
|
| +
|
| +Schedule* InterpreterAssembler::schedule() {
|
| + return raw_assembler_->schedule();
|
| +}
|
| +
|
| +
|
| +MachineOperatorBuilder* InterpreterAssembler::machine() {
|
| + return raw_assembler_->machine();
|
| +}
|
| +
|
| +
|
| +CommonOperatorBuilder* InterpreterAssembler::common() {
|
| + return raw_assembler_->common();
|
| +}
|
| +
|
| +
|
| +Node* InterpreterAssembler::Int32Constant(int value) {
|
| + return raw_assembler_->Int32Constant(value);
|
| +}
|
| +
|
| +
|
| +Node* InterpreterAssembler::NumberConstant(double value) {
|
| + return raw_assembler_->NumberConstant(value);
|
| +}
|
| +
|
| +
|
| +} // namespace interpreter
|
| +} // namespace internal
|
| +} // namespace v8
|
|
|