Commit 63096bc8 authored by jgruber's avatar jgruber Committed by Commit bot

[ic] Inline LoadGlobalIC in bytecode handlers

Instead of calling the LoadGlobalIC stub, bytecode handlers now inline
logic for LoadGlobalIC. The LoadGlobalICData case takes a fast path
which omits name loading and frame construction.

BUG=v8:5917

Review-Url: https://codereview.chromium.org/2684973002
Cr-Commit-Position: refs/heads/master@{#43210}
parent fdc78d29
......@@ -15,6 +15,7 @@
#include "src/compilation-info.h"
#include "src/compiler.h"
#include "src/factory.h"
#include "src/ic/accessor-assembler.h"
#include "src/interpreter/bytecode-flags.h"
#include "src/interpreter/bytecode-generator.h"
#include "src/interpreter/bytecodes.h"
......@@ -478,16 +479,71 @@ void Interpreter::DoMov(InterpreterAssembler* assembler) {
__ Dispatch();
}
Node* Interpreter::BuildLoadGlobal(Callable ic, Node* context, Node* name_index,
Node* feedback_slot,
InterpreterAssembler* assembler) {
void Interpreter::BuildLoadGlobal(int slot_operand_index,
int name_operand_index,
TypeofMode typeof_mode,
InterpreterAssembler* assembler) {
// Load the global via the LoadGlobalIC.
Node* code_target = __ HeapConstant(ic.code());
Node* name = __ LoadConstantPoolEntry(name_index);
Node* smi_slot = __ SmiTag(feedback_slot);
Node* feedback_vector = __ LoadFeedbackVector();
return __ CallStub(ic.descriptor(), code_target, context, name, smi_slot,
feedback_vector);
Node* feedback_slot = __ BytecodeOperandIdx(slot_operand_index);
AccessorAssembler accessor_asm(assembler->state());
Label try_handler(assembler, Label::kDeferred),
miss(assembler, Label::kDeferred);
// Fast path without frame construction for the data case.
{
Label done(assembler);
Variable var_result(assembler, MachineRepresentation::kTagged);
ExitPoint exit_point(assembler, &done, &var_result);
accessor_asm.LoadGlobalIC_TryPropertyCellCase(
feedback_vector, feedback_slot, &exit_point, &try_handler, &miss,
CodeStubAssembler::INTPTR_PARAMETERS);
__ Bind(&done);
__ SetAccumulator(var_result.value());
__ Dispatch();
}
// Slow path with frame construction.
{
Label done(assembler);
Variable var_result(assembler, MachineRepresentation::kTagged);
ExitPoint exit_point(assembler, &done, &var_result);
__ Bind(&try_handler);
{
Node* context = __ GetContext();
Node* smi_slot = __ SmiTag(feedback_slot);
Node* name_index = __ BytecodeOperandIdx(name_operand_index);
Node* name = __ LoadConstantPoolEntry(name_index);
AccessorAssembler::LoadICParameters params(context, nullptr, name,
smi_slot, feedback_vector);
accessor_asm.LoadGlobalIC_TryHandlerCase(&params, typeof_mode,
&exit_point, &miss);
}
__ Bind(&miss);
{
Node* context = __ GetContext();
Node* smi_slot = __ SmiTag(feedback_slot);
Node* name_index = __ BytecodeOperandIdx(name_operand_index);
Node* name = __ LoadConstantPoolEntry(name_index);
AccessorAssembler::LoadICParameters params(context, nullptr, name,
smi_slot, feedback_vector);
accessor_asm.LoadGlobalIC_MissCase(&params, &exit_point);
}
__ Bind(&done);
{
__ SetAccumulator(var_result.value());
__ Dispatch();
}
}
}
// LdaGlobal <name_index> <slot>
......@@ -495,16 +551,11 @@ Node* Interpreter::BuildLoadGlobal(Callable ic, Node* context, Node* name_index,
// Load the global with name in constant pool entry <name_index> into the
// accumulator using FeedBackVector slot <slot> outside of a typeof.
void Interpreter::DoLdaGlobal(InterpreterAssembler* assembler) {
Callable ic =
CodeFactory::LoadGlobalICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF);
static const int kNameOperandIndex = 0;
static const int kSlotOperandIndex = 1;
Node* context = __ GetContext();
Node* name_index = __ BytecodeOperandIdx(0);
Node* raw_slot = __ BytecodeOperandIdx(1);
Node* result = BuildLoadGlobal(ic, context, name_index, raw_slot, assembler);
__ SetAccumulator(result);
__ Dispatch();
BuildLoadGlobal(kSlotOperandIndex, kNameOperandIndex, NOT_INSIDE_TYPEOF,
assembler);
}
// LdaGlobalInsideTypeof <name_index> <slot>
......@@ -512,16 +563,11 @@ void Interpreter::DoLdaGlobal(InterpreterAssembler* assembler) {
// Load the global with name in constant pool entry <name_index> into the
// accumulator using FeedBackVector slot <slot> inside of a typeof.
void Interpreter::DoLdaGlobalInsideTypeof(InterpreterAssembler* assembler) {
Callable ic =
CodeFactory::LoadGlobalICInOptimizedCode(isolate_, INSIDE_TYPEOF);
Node* context = __ GetContext();
static const int kNameOperandIndex = 0;
static const int kSlotOperandIndex = 1;
Node* name_index = __ BytecodeOperandIdx(0);
Node* raw_slot = __ BytecodeOperandIdx(1);
Node* result = BuildLoadGlobal(ic, context, name_index, raw_slot, assembler);
__ SetAccumulator(result);
__ Dispatch();
BuildLoadGlobal(kSlotOperandIndex, kNameOperandIndex, INSIDE_TYPEOF,
assembler);
}
void Interpreter::DoStaGlobal(Callable ic, InterpreterAssembler* assembler) {
......@@ -709,8 +755,6 @@ void Interpreter::DoLdaLookupContextSlotInsideTypeof(
void Interpreter::DoLdaLookupGlobalSlot(Runtime::FunctionId function_id,
InterpreterAssembler* assembler) {
Node* context = __ GetContext();
Node* name_index = __ BytecodeOperandIdx(0);
Node* feedback_slot = __ BytecodeOperandIdx(1);
Node* depth = __ BytecodeOperandUImm(2);
Label slowpath(assembler, Label::kDeferred);
......@@ -720,19 +764,21 @@ void Interpreter::DoLdaLookupGlobalSlot(Runtime::FunctionId function_id,
// Fast path does a normal load global
{
Callable ic = CodeFactory::LoadGlobalICInOptimizedCode(
isolate_, function_id == Runtime::kLoadLookupSlotInsideTypeof
? INSIDE_TYPEOF
: NOT_INSIDE_TYPEOF);
Node* result =
BuildLoadGlobal(ic, context, name_index, feedback_slot, assembler);
__ SetAccumulator(result);
__ Dispatch();
static const int kNameOperandIndex = 0;
static const int kSlotOperandIndex = 1;
TypeofMode typeof_mode = function_id == Runtime::kLoadLookupSlotInsideTypeof
? INSIDE_TYPEOF
: NOT_INSIDE_TYPEOF;
BuildLoadGlobal(kSlotOperandIndex, kNameOperandIndex, typeof_mode,
assembler);
}
// Slow path when we have to call out to the runtime
__ Bind(&slowpath);
{
Node* name_index = __ BytecodeOperandIdx(0);
Node* name = __ LoadConstantPoolEntry(name_index);
Node* result = __ CallRuntime(function_id, context, name);
__ SetAccumulator(result);
......
......@@ -148,10 +148,8 @@ class Interpreter {
InterpreterAssembler* assembler);
// Generates code to load a global.
compiler::Node* BuildLoadGlobal(Callable ic, compiler::Node* context,
compiler::Node* name_index,
compiler::Node* feedback_slot,
InterpreterAssembler* assembler);
void BuildLoadGlobal(int slot_operand_index, int name_operand_index,
TypeofMode typeof_mode, InterpreterAssembler* assembler);
// Generates code to prepare the result for ForInPrepare. Cache data
// are placed into the consecutive series of registers starting at
......
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