Commit 91009c50 authored by yangguo's avatar yangguo Committed by Commit bot

[interpreter] move the dispatch table off heap.

This makes the dispatch table similar to the builtins code list and makes
sure that the dispatch table does not move.

R=mstarzinger@chromium.org, rmcilroy@chromium.org

Review URL: https://codereview.chromium.org/1671813003

Cr-Commit-Position: refs/heads/master@{#33781}
parent 334d1794
......@@ -1049,10 +1049,9 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
Operand(InterpreterFrameConstants::kRegisterFilePointerFromFp));
__ mov(kInterpreterBytecodeOffsetRegister,
Operand(BytecodeArray::kHeaderSize - kHeapObjectTag));
__ LoadRoot(kInterpreterDispatchTableRegister,
Heap::kInterpreterTableRootIndex);
__ add(kInterpreterDispatchTableRegister, kInterpreterDispatchTableRegister,
Operand(FixedArray::kHeaderSize - kHeapObjectTag));
__ mov(kInterpreterDispatchTableRegister,
Operand(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));
// Dispatch to the first bytecode handler for the function.
__ ldrb(r1, MemOperand(kInterpreterBytecodeArrayRegister,
......@@ -1154,10 +1153,9 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
// Initialize register file register and dispatch table register.
__ add(kInterpreterRegisterFileRegister, fp,
Operand(InterpreterFrameConstants::kRegisterFilePointerFromFp));
__ LoadRoot(kInterpreterDispatchTableRegister,
Heap::kInterpreterTableRootIndex);
__ add(kInterpreterDispatchTableRegister, kInterpreterDispatchTableRegister,
Operand(FixedArray::kHeaderSize - kHeapObjectTag));
__ mov(kInterpreterDispatchTableRegister,
Operand(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));
// Get the context from the frame.
__ ldr(kContextRegister,
......
......@@ -1059,10 +1059,9 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
Operand(InterpreterFrameConstants::kRegisterFilePointerFromFp));
__ Mov(kInterpreterBytecodeOffsetRegister,
Operand(BytecodeArray::kHeaderSize - kHeapObjectTag));
__ LoadRoot(kInterpreterDispatchTableRegister,
Heap::kInterpreterTableRootIndex);
__ Add(kInterpreterDispatchTableRegister, kInterpreterDispatchTableRegister,
Operand(FixedArray::kHeaderSize - kHeapObjectTag));
__ Mov(kInterpreterDispatchTableRegister,
Operand(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));
// Dispatch to the first bytecode handler for the function.
__ Ldrb(x1, MemOperand(kInterpreterBytecodeArrayRegister,
......@@ -1103,10 +1102,9 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
// Initialize register file register and dispatch table register.
__ Add(kInterpreterRegisterFileRegister, fp,
Operand(InterpreterFrameConstants::kRegisterFilePointerFromFp));
__ LoadRoot(kInterpreterDispatchTableRegister,
Heap::kInterpreterTableRootIndex);
__ Add(kInterpreterDispatchTableRegister, kInterpreterDispatchTableRegister,
Operand(FixedArray::kHeaderSize - kHeapObjectTag));
__ Mov(kInterpreterDispatchTableRegister,
Operand(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));
// Get the context from the frame.
__ Ldr(kContextRegister,
......
......@@ -51,6 +51,7 @@
#include "src/execution.h"
#include "src/ic/ic.h"
#include "src/ic/stub-cache.h"
#include "src/interpreter/interpreter.h"
#include "src/ostreams.h"
#include "src/profiler/cpu-profiler.h"
#include "src/regexp/jsregexp.h"
......@@ -1052,6 +1053,10 @@ ExternalReference ExternalReference::isolate_address(Isolate* isolate) {
return ExternalReference(isolate);
}
ExternalReference ExternalReference::interpreter_dispatch_table_address(
Isolate* isolate) {
return ExternalReference(isolate->interpreter()->dispatch_table_address());
}
ExternalReference::ExternalReference(StatsCounter* counter)
: address_(reinterpret_cast<Address>(counter->GetInternalPointer())) {}
......
......@@ -897,6 +897,8 @@ class ExternalReference BASE_EMBEDDED {
// pattern. This means that they have to be added to the
// ExternalReferenceTable in serialize.cc manually.
static ExternalReference interpreter_dispatch_table_address(Isolate* isolate);
static ExternalReference incremental_marking_record_write_function(
Isolate* isolate);
static ExternalReference incremental_marking_record_write_code_entry_function(
......
......@@ -2871,11 +2871,6 @@ void Heap::CreateInitialObjects() {
set_noscript_shared_function_infos(Smi::FromInt(0));
// Will be filled in by Interpreter::Initialize().
set_interpreter_table(
*interpreter::Interpreter::CreateUninitializedInterpreterTable(
isolate()));
// Initialize keyed lookup cache.
isolate_->keyed_lookup_cache()->Clear();
......@@ -4605,8 +4600,10 @@ void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) {
// on scavenge collections.
if (mode != VISIT_ALL_IN_SCAVENGE) {
isolate_->builtins()->IterateBuiltins(v);
v->Synchronize(VisitorSynchronization::kBuiltins);
isolate_->interpreter()->IterateDispatchTable(v);
v->Synchronize(VisitorSynchronization::kDispatchTable);
}
v->Synchronize(VisitorSynchronization::kBuiltins);
// Iterate over global handles.
switch (mode) {
......
......@@ -188,7 +188,6 @@ namespace internal {
V(PropertyCell, empty_property_cell, EmptyPropertyCell) \
V(Object, weak_stack_trace_list, WeakStackTraceList) \
V(Object, noscript_shared_function_infos, NoScriptSharedFunctionInfos) \
V(FixedArray, interpreter_table, InterpreterTable) \
V(Map, bytecode_array_map, BytecodeArrayMap) \
V(WeakCell, empty_weak_cell, EmptyWeakCell)
......
......@@ -608,10 +608,8 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
Immediate(InterpreterFrameConstants::kRegisterFilePointerFromFp));
__ mov(kInterpreterBytecodeOffsetRegister,
Immediate(BytecodeArray::kHeaderSize - kHeapObjectTag));
// Since the dispatch table root might be set after builtins are generated,
// load directly from the roots table.
__ LoadRoot(ebx, Heap::kInterpreterTableRootIndex);
__ add(ebx, Immediate(FixedArray::kHeaderSize - kHeapObjectTag));
__ mov(ebx, Immediate(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));
// Push dispatch table as a stack located parameter to the bytecode handler.
DCHECK_EQ(-1, kInterpreterDispatchTableSpillSlot);
......@@ -773,8 +771,8 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
__ SmiUntag(kInterpreterBytecodeOffsetRegister);
// Push dispatch table as a stack located parameter to the bytecode handler.
__ LoadRoot(ebx, Heap::kInterpreterTableRootIndex);
__ add(ebx, Immediate(FixedArray::kHeaderSize - kHeapObjectTag));
__ mov(ebx, Immediate(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));
DCHECK_EQ(-1, kInterpreterDispatchTableSpillSlot);
__ Pop(esi);
__ Push(ebx);
......
......@@ -21,42 +21,33 @@ using compiler::Node;
#define __ assembler->
Interpreter::Interpreter(Isolate* isolate)
: isolate_(isolate) {}
// static
Handle<FixedArray> Interpreter::CreateUninitializedInterpreterTable(
Isolate* isolate) {
Handle<FixedArray> handler_table = isolate->factory()->NewFixedArray(
static_cast<int>(Bytecode::kLast) + 1, TENURED);
// We rely on the interpreter handler table being immovable, so check that
// it was allocated on the first page (which is always immovable).
DCHECK(isolate->heap()->old_space()->FirstPage()->Contains(
handler_table->address()));
return handler_table;
Interpreter::Interpreter(Isolate* isolate) : isolate_(isolate) {
memset(&dispatch_table_, 0, sizeof(dispatch_table_));
}
void Interpreter::Initialize() {
DCHECK(FLAG_ignition);
Handle<FixedArray> handler_table = isolate_->factory()->interpreter_table();
if (!IsInterpreterTableInitialized(handler_table)) {
Zone zone;
HandleScope scope(isolate_);
#define GENERATE_CODE(Name, ...) \
{ \
compiler::InterpreterAssembler assembler(isolate_, &zone, \
Bytecode::k##Name); \
Do##Name(&assembler); \
Handle<Code> code = assembler.GenerateCode(); \
handler_table->set(static_cast<int>(Bytecode::k##Name), *code); \
}
BYTECODE_LIST(GENERATE_CODE)
#undef GENERATE_CODE
if (IsDispatchTableInitialized()) return;
Zone zone;
HandleScope scope(isolate_);
#define GENERATE_CODE(Name, ...) \
{ \
compiler::InterpreterAssembler assembler(isolate_, &zone, \
Bytecode::k##Name); \
Do##Name(&assembler); \
Handle<Code> code = assembler.GenerateCode(); \
int index = static_cast<int>(Bytecode::k##Name); \
dispatch_table_[index] = *code; \
}
BYTECODE_LIST(GENERATE_CODE)
#undef GENERATE_CODE
}
void Interpreter::IterateDispatchTable(ObjectVisitor* v) {
v->VisitPointers(&dispatch_table_[0],
&dispatch_table_[0] + kDispatchTableSize);
}
......@@ -100,15 +91,12 @@ bool Interpreter::MakeBytecode(CompilationInfo* info) {
return true;
}
bool Interpreter::IsInterpreterTableInitialized(
Handle<FixedArray> handler_table) {
bool Interpreter::IsDispatchTableInitialized() {
if (FLAG_trace_ignition) {
// Regenerate table to add bytecode tracing operations.
return false;
}
DCHECK(handler_table->length() == static_cast<int>(Bytecode::kLast) + 1);
return handler_table->get(0) != isolate_->heap()->undefined_value();
return dispatch_table_[0] != nullptr;
}
// LdaZero
......
......@@ -32,17 +32,19 @@ class Interpreter {
explicit Interpreter(Isolate* isolate);
virtual ~Interpreter() {}
// Creates an uninitialized interpreter handler table, where each handler
// points to the Illegal builtin.
static Handle<FixedArray> CreateUninitializedInterpreterTable(
Isolate* isolate);
// Initializes the interpreter.
// Initializes the interpreter dispatch table.
void Initialize();
// Generate bytecode for |info|.
static bool MakeBytecode(CompilationInfo* info);
// GC support.
void IterateDispatchTable(ObjectVisitor* v);
Address dispatch_table_address() {
return reinterpret_cast<Address>(&dispatch_table_[0]);
}
private:
// Bytecode handler generator functions.
#define DECLARE_BYTECODE_HANDLER_GENERATOR(Name, ...) \
......@@ -115,9 +117,12 @@ class Interpreter {
void DoStoreLookupSlot(LanguageMode language_mode,
compiler::InterpreterAssembler* assembler);
bool IsInterpreterTableInitialized(Handle<FixedArray> handler_table);
bool IsDispatchTableInitialized();
static const int kDispatchTableSize = static_cast<int>(Bytecode::kLast) + 1;
Isolate* isolate_;
Object* dispatch_table_[kDispatchTableSize];
DISALLOW_COPY_AND_ASSIGN(Interpreter);
};
......
......@@ -1926,9 +1926,6 @@ void Isolate::Deinit() {
Sampler* sampler = logger_->sampler();
if (sampler && sampler->IsActive()) sampler->Stop();
delete interpreter_;
interpreter_ = NULL;
delete deoptimizer_data_;
deoptimizer_data_ = NULL;
builtins_.TearDown();
......@@ -1948,6 +1945,9 @@ void Isolate::Deinit() {
heap_.TearDown();
logger_->TearDown();
delete interpreter_;
interpreter_ = NULL;
cancelable_task_manager()->CancelAndWait();
delete cpu_profiler_;
......
......@@ -1037,10 +1037,9 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
Operand(InterpreterFrameConstants::kRegisterFilePointerFromFp));
__ li(kInterpreterBytecodeOffsetRegister,
Operand(BytecodeArray::kHeaderSize - kHeapObjectTag));
__ LoadRoot(kInterpreterDispatchTableRegister,
Heap::kInterpreterTableRootIndex);
__ Addu(kInterpreterDispatchTableRegister, kInterpreterDispatchTableRegister,
Operand(FixedArray::kHeaderSize - kHeapObjectTag));
__ li(kInterpreterDispatchTableRegister,
Operand(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));
// Dispatch to the first bytecode handler for the function.
__ Addu(a0, kInterpreterBytecodeArrayRegister,
......@@ -1141,10 +1140,9 @@ void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
// Initialize register file register and dispatch table register.
__ Addu(kInterpreterRegisterFileRegister, fp,
Operand(InterpreterFrameConstants::kRegisterFilePointerFromFp));
__ LoadRoot(kInterpreterDispatchTableRegister,
Heap::kInterpreterTableRootIndex);
__ li(kInterpreterDispatchTableRegister,
Operand(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));
__ Addu(kInterpreterDispatchTableRegister, kInterpreterDispatchTableRegister,
Operand(FixedArray::kHeaderSize - kHeapObjectTag));
......
......@@ -1030,10 +1030,9 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
Operand(InterpreterFrameConstants::kRegisterFilePointerFromFp));
__ li(kInterpreterBytecodeOffsetRegister,
Operand(BytecodeArray::kHeaderSize - kHeapObjectTag));
__ LoadRoot(kInterpreterDispatchTableRegister,
Heap::kInterpreterTableRootIndex);
__ Daddu(kInterpreterDispatchTableRegister, kInterpreterDispatchTableRegister,
Operand(FixedArray::kHeaderSize - kHeapObjectTag));
__ li(kInterpreterDispatchTableRegister,
Operand(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));
// Dispatch to the first bytecode handler for the function.
__ Daddu(a0, kInterpreterBytecodeArrayRegister,
......@@ -1136,10 +1135,9 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
// Initialize register file register and dispatch table register.
__ Daddu(kInterpreterRegisterFileRegister, fp,
Operand(InterpreterFrameConstants::kRegisterFilePointerFromFp));
__ LoadRoot(kInterpreterDispatchTableRegister,
Heap::kInterpreterTableRootIndex);
__ Daddu(kInterpreterDispatchTableRegister, kInterpreterDispatchTableRegister,
Operand(FixedArray::kHeaderSize - kHeapObjectTag));
__ li(kInterpreterDispatchTableRegister,
Operand(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));
// Get the context from the frame.
__ ld(kContextRegister,
......
......@@ -10708,6 +10708,7 @@ class BreakPointInfo: public Struct {
V(kDebug, "debug", "(Debugger)") \
V(kCompilationCache, "compilationcache", "(Compilation cache)") \
V(kHandleScope, "handlescope", "(Handle scope)") \
V(kDispatchTable, "dispatchtable", "(Dispatch table)") \
V(kBuiltins, "builtins", "(Builtins)") \
V(kGlobalHandles, "globalhandles", "(Global handles)") \
V(kEternalHandles, "eternalhandles", "(Eternal handles)") \
......
......@@ -1039,10 +1039,9 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
Operand(InterpreterFrameConstants::kRegisterFilePointerFromFp));
__ mov(kInterpreterBytecodeOffsetRegister,
Operand(BytecodeArray::kHeaderSize - kHeapObjectTag));
__ LoadRoot(kInterpreterDispatchTableRegister,
Heap::kInterpreterTableRootIndex);
__ addi(kInterpreterDispatchTableRegister, kInterpreterDispatchTableRegister,
Operand(FixedArray::kHeaderSize - kHeapObjectTag));
__ mov(kInterpreterDispatchTableRegister,
Operand(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));
// Dispatch to the first bytecode handler for the function.
__ lbzx(r4, MemOperand(kInterpreterBytecodeArrayRegister,
......@@ -1141,10 +1140,9 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
// Initialize register file register and dispatch table register.
__ addi(kInterpreterRegisterFileRegister, fp,
Operand(InterpreterFrameConstants::kRegisterFilePointerFromFp));
__ LoadRoot(kInterpreterDispatchTableRegister,
Heap::kInterpreterTableRootIndex);
__ addi(kInterpreterDispatchTableRegister, kInterpreterDispatchTableRegister,
Operand(FixedArray::kHeaderSize - kHeapObjectTag));
__ mov(kInterpreterDispatchTableRegister,
Operand(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));
// Get the context from the frame.
__ LoadP(kContextRegister,
......
......@@ -82,6 +82,8 @@ ExternalReferenceTable::ExternalReferenceTable(Isolate* isolate) {
Add(ExternalReference::address_of_one_half().address(),
"LDoubleConstant::one_half");
Add(ExternalReference::isolate_address(isolate).address(), "isolate");
Add(ExternalReference::interpreter_dispatch_table_address(isolate).address(),
"Interpreter::dispatch_table_address");
Add(ExternalReference::address_of_negative_infinity().address(),
"LDoubleConstant::negative_infinity");
Add(ExternalReference::power_double_double_function(isolate).address(),
......
......@@ -678,10 +678,9 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
Immediate(InterpreterFrameConstants::kRegisterFilePointerFromFp));
__ movp(kInterpreterBytecodeOffsetRegister,
Immediate(BytecodeArray::kHeaderSize - kHeapObjectTag));
__ LoadRoot(kInterpreterDispatchTableRegister,
Heap::kInterpreterTableRootIndex);
__ addp(kInterpreterDispatchTableRegister,
Immediate(FixedArray::kHeaderSize - kHeapObjectTag));
__ Move(
kInterpreterDispatchTableRegister,
ExternalReference::interpreter_dispatch_table_address(masm->isolate()));
// Dispatch to the first bytecode handler for the function.
__ movzxbp(rbx, Operand(kInterpreterBytecodeArrayRegister,
......@@ -805,10 +804,9 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
__ movp(kInterpreterRegisterFileRegister, rbp);
__ addp(kInterpreterRegisterFileRegister,
Immediate(InterpreterFrameConstants::kRegisterFilePointerFromFp));
__ LoadRoot(kInterpreterDispatchTableRegister,
Heap::kInterpreterTableRootIndex);
__ addp(kInterpreterDispatchTableRegister,
Immediate(FixedArray::kHeaderSize - kHeapObjectTag));
__ Move(
kInterpreterDispatchTableRegister,
ExternalReference::interpreter_dispatch_table_address(masm->isolate()));
// Get the context from the frame.
__ movp(kContextRegister,
......
......@@ -609,10 +609,8 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
Immediate(InterpreterFrameConstants::kRegisterFilePointerFromFp));
__ mov(kInterpreterBytecodeOffsetRegister,
Immediate(BytecodeArray::kHeaderSize - kHeapObjectTag));
// Since the dispatch table root might be set after builtins are generated,
// load directly from the roots table.
__ LoadRoot(ebx, Heap::kInterpreterTableRootIndex);
__ add(ebx, Immediate(FixedArray::kHeaderSize - kHeapObjectTag));
__ mov(ebx, Immediate(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));
// Push dispatch table as a stack located parameter to the bytecode handler.
DCHECK_EQ(-1, kInterpreterDispatchTableSpillSlot);
......@@ -774,8 +772,8 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
__ SmiUntag(kInterpreterBytecodeOffsetRegister);
// Push dispatch table as a stack located parameter to the bytecode handler.
__ LoadRoot(ebx, Heap::kInterpreterTableRootIndex);
__ add(ebx, Immediate(FixedArray::kHeaderSize - kHeapObjectTag));
__ mov(ebx, Immediate(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));
DCHECK_EQ(-1, kInterpreterDispatchTableSpillSlot);
__ Pop(esi);
__ Push(ebx);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment