Commit 6173d504 authored by rmcilroy's avatar rmcilroy Committed by Commit bot

[Interpreter] Add wide varients of bytecodes with feedback and constant pool indexes.

Adds wide bytecode varients, which take 16-bit feedback slot and constant
pool entry indexes for the following bytecodes:
  - LoadICSloppyWide
  - LoadICStrictWide
  - KeyedLoadICSloppyWide
  - KeyedLoadICStrictWide
  - StoreICSloppyWide
  - StoreICStrictWide
  - KeyedStoreICSloppyWide
  - KeyedStoreICStrictWide
  - LdaGlobalSloppyWide
  - LdaGlobalStrictWide
  - StaGlobalSloppyWide
  - StaGlobalStrictWide
  - LdaConstantWide

BUG=v8:4280
LOG=N

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

Cr-Commit-Position: refs/heads/master@{#31683}
parent b1f00106
......@@ -193,6 +193,13 @@ void BytecodeGraphBuilder::VisitLdaSmi8(
}
void BytecodeGraphBuilder::VisitLdaConstantWide(
const interpreter::BytecodeArrayIterator& iterator) {
Node* node = jsgraph()->Constant(iterator.GetConstantForIndexOperand(0));
environment()->BindAccumulator(node);
}
void BytecodeGraphBuilder::VisitLdaConstant(
const interpreter::BytecodeArrayIterator& iterator) {
Node* node = jsgraph()->Constant(iterator.GetConstantForIndexOperand(0));
......@@ -261,6 +268,18 @@ void BytecodeGraphBuilder::VisitLdaGlobalStrict(
}
void BytecodeGraphBuilder::VisitLdaGlobalSloppyWide(
const interpreter::BytecodeArrayIterator& iterator) {
UNIMPLEMENTED();
}
void BytecodeGraphBuilder::VisitLdaGlobalStrictWide(
const interpreter::BytecodeArrayIterator& iterator) {
UNIMPLEMENTED();
}
void BytecodeGraphBuilder::VisitStaGlobalSloppy(
const interpreter::BytecodeArrayIterator& iterator) {
UNIMPLEMENTED();
......@@ -272,6 +291,17 @@ void BytecodeGraphBuilder::VisitStaGlobalStrict(
UNIMPLEMENTED();
}
void BytecodeGraphBuilder::VisitStaGlobalSloppyWide(
const interpreter::BytecodeArrayIterator& iterator) {
UNIMPLEMENTED();
}
void BytecodeGraphBuilder::VisitStaGlobalStrictWide(
const interpreter::BytecodeArrayIterator& iterator) {
UNIMPLEMENTED();
}
void BytecodeGraphBuilder::VisitLdaContextSlot(
const interpreter::BytecodeArrayIterator& iterator) {
......@@ -309,6 +339,30 @@ void BytecodeGraphBuilder::VisitKeyedLoadICStrict(
}
void BytecodeGraphBuilder::VisitLoadICSloppyWide(
const interpreter::BytecodeArrayIterator& iterator) {
UNIMPLEMENTED();
}
void BytecodeGraphBuilder::VisitLoadICStrictWide(
const interpreter::BytecodeArrayIterator& iterator) {
UNIMPLEMENTED();
}
void BytecodeGraphBuilder::VisitKeyedLoadICSloppyWide(
const interpreter::BytecodeArrayIterator& iterator) {
UNIMPLEMENTED();
}
void BytecodeGraphBuilder::VisitKeyedLoadICStrictWide(
const interpreter::BytecodeArrayIterator& iterator) {
UNIMPLEMENTED();
}
void BytecodeGraphBuilder::VisitStoreICSloppy(
const interpreter::BytecodeArrayIterator& iterator) {
UNIMPLEMENTED();
......@@ -333,6 +387,30 @@ void BytecodeGraphBuilder::VisitKeyedStoreICStrict(
}
void BytecodeGraphBuilder::VisitStoreICSloppyWide(
const interpreter::BytecodeArrayIterator& iterator) {
UNIMPLEMENTED();
}
void BytecodeGraphBuilder::VisitStoreICStrictWide(
const interpreter::BytecodeArrayIterator& iterator) {
UNIMPLEMENTED();
}
void BytecodeGraphBuilder::VisitKeyedStoreICSloppyWide(
const interpreter::BytecodeArrayIterator& iterator) {
UNIMPLEMENTED();
}
void BytecodeGraphBuilder::VisitKeyedStoreICStrictWide(
const interpreter::BytecodeArrayIterator& iterator) {
UNIMPLEMENTED();
}
void BytecodeGraphBuilder::VisitPushContext(
const interpreter::BytecodeArrayIterator& iterator) {
UNIMPLEMENTED();
......
......@@ -192,41 +192,46 @@ Node* InterpreterAssembler::BytecodeOperandShort(int operand_index) {
}
Node* InterpreterAssembler::BytecodeOperandCount8(int operand_index) {
Node* InterpreterAssembler::BytecodeOperandCount(int operand_index) {
DCHECK_EQ(interpreter::OperandType::kCount8,
interpreter::Bytecodes::GetOperandType(bytecode_, operand_index));
return BytecodeOperand(operand_index);
}
Node* InterpreterAssembler::BytecodeOperandImm8(int operand_index) {
Node* InterpreterAssembler::BytecodeOperandImm(int operand_index) {
DCHECK_EQ(interpreter::OperandType::kImm8,
interpreter::Bytecodes::GetOperandType(bytecode_, operand_index));
return BytecodeOperandSignExtended(operand_index);
}
Node* InterpreterAssembler::BytecodeOperandIdx8(int operand_index) {
DCHECK_EQ(interpreter::OperandType::kIdx8,
interpreter::Bytecodes::GetOperandType(bytecode_, operand_index));
return BytecodeOperand(operand_index);
Node* InterpreterAssembler::BytecodeOperandIdx(int operand_index) {
switch (interpreter::Bytecodes::GetOperandSize(bytecode_, operand_index)) {
case interpreter::OperandSize::kByte:
DCHECK_EQ(
interpreter::OperandType::kIdx8,
interpreter::Bytecodes::GetOperandType(bytecode_, operand_index));
return BytecodeOperand(operand_index);
case interpreter::OperandSize::kShort:
DCHECK_EQ(
interpreter::OperandType::kIdx16,
interpreter::Bytecodes::GetOperandType(bytecode_, operand_index));
return BytecodeOperandShort(operand_index);
default:
UNREACHABLE();
return nullptr;
}
}
Node* InterpreterAssembler::BytecodeOperandReg8(int operand_index) {
Node* InterpreterAssembler::BytecodeOperandReg(int operand_index) {
DCHECK_EQ(interpreter::OperandType::kReg8,
interpreter::Bytecodes::GetOperandType(bytecode_, operand_index));
return BytecodeOperandSignExtended(operand_index);
}
Node* InterpreterAssembler::BytecodeOperandIdx16(int operand_index) {
DCHECK_EQ(interpreter::OperandType::kIdx16,
interpreter::Bytecodes::GetOperandType(bytecode_, operand_index));
return BytecodeOperandShort(operand_index);
}
Node* InterpreterAssembler::Int32Constant(int value) {
return raw_assembler_->Int32Constant(value);
}
......
......@@ -41,20 +41,16 @@ class InterpreterAssembler {
// Returns the count immediate for bytecode operand |operand_index| in the
// current bytecode.
Node* BytecodeOperandCount8(int operand_index);
Node* BytecodeOperandCount(int operand_index);
// Returns the index immediate for bytecode operand |operand_index| in the
// current bytecode.
Node* BytecodeOperandIdx8(int operand_index);
Node* BytecodeOperandIdx(int operand_index);
// Returns the Imm8 immediate for bytecode operand |operand_index| in the
// current bytecode.
Node* BytecodeOperandImm8(int operand_index);
Node* BytecodeOperandImm(int operand_index);
// Returns the register index for bytecode operand |operand_index| in the
// current bytecode.
Node* BytecodeOperandReg8(int operand_index);
// Returns the index immediate for the short (16 bit) bytecode operand
// |operand_index| in the current bytecode.
Node* BytecodeOperandIdx16(int operand_index);
Node* BytecodeOperandReg(int operand_index);
// Accumulator.
Node* GetAccumulator();
......
......@@ -224,6 +224,8 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(Handle<Object> object) {
size_t entry = GetConstantPoolEntry(object);
if (FitsInIdx8Operand(entry)) {
Output(Bytecode::kLdaConstant, static_cast<uint8_t>(entry));
} else if (FitsInIdx16Operand(entry)) {
Output(Bytecode::kLdaConstantWide, static_cast<uint16_t>(entry));
} else {
UNIMPLEMENTED();
}
......@@ -285,6 +287,10 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal(
if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) {
Output(bytecode, static_cast<uint8_t>(name_index),
static_cast<uint8_t>(feedback_slot));
} else if (FitsInIdx16Operand(name_index) &&
FitsInIdx16Operand(feedback_slot)) {
Output(BytecodeForWideOperands(bytecode), static_cast<uint16_t>(name_index),
static_cast<uint16_t>(feedback_slot));
} else {
UNIMPLEMENTED();
}
......@@ -298,6 +304,10 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StoreGlobal(
if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) {
Output(bytecode, static_cast<uint8_t>(name_index),
static_cast<uint8_t>(feedback_slot));
} else if (FitsInIdx16Operand(name_index) &&
FitsInIdx16Operand(feedback_slot)) {
Output(BytecodeForWideOperands(bytecode), static_cast<uint16_t>(name_index),
static_cast<uint16_t>(feedback_slot));
} else {
UNIMPLEMENTED();
}
......@@ -338,6 +348,11 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty(
if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) {
Output(bytecode, object.ToOperand(), static_cast<uint8_t>(name_index),
static_cast<uint8_t>(feedback_slot));
} else if (FitsInIdx16Operand(name_index) &&
FitsInIdx16Operand(feedback_slot)) {
Output(BytecodeForWideOperands(bytecode), object.ToOperand(),
static_cast<uint16_t>(name_index),
static_cast<uint16_t>(feedback_slot));
} else {
UNIMPLEMENTED();
}
......@@ -350,6 +365,9 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty(
Bytecode bytecode = BytecodeForKeyedLoadIC(language_mode);
if (FitsInIdx8Operand(feedback_slot)) {
Output(bytecode, object.ToOperand(), static_cast<uint8_t>(feedback_slot));
} else if (FitsInIdx16Operand(feedback_slot)) {
Output(BytecodeForWideOperands(bytecode), object.ToOperand(),
static_cast<uint16_t>(feedback_slot));
} else {
UNIMPLEMENTED();
}
......@@ -364,6 +382,11 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty(
if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) {
Output(bytecode, object.ToOperand(), static_cast<uint8_t>(name_index),
static_cast<uint8_t>(feedback_slot));
} else if (FitsInIdx16Operand(name_index) &&
FitsInIdx16Operand(feedback_slot)) {
Output(BytecodeForWideOperands(bytecode), object.ToOperand(),
static_cast<uint16_t>(name_index),
static_cast<uint16_t>(feedback_slot));
} else {
UNIMPLEMENTED();
}
......@@ -378,6 +401,9 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty(
if (FitsInIdx8Operand(feedback_slot)) {
Output(bytecode, object.ToOperand(), key.ToOperand(),
static_cast<uint8_t>(feedback_slot));
} else if (FitsInIdx16Operand(feedback_slot)) {
Output(BytecodeForWideOperands(bytecode), object.ToOperand(),
key.ToOperand(), static_cast<uint16_t>(feedback_slot));
} else {
UNIMPLEMENTED();
}
......@@ -951,6 +977,40 @@ Bytecode BytecodeArrayBuilder::BytecodeForCompareOperation(Token::Value op) {
}
// static
Bytecode BytecodeArrayBuilder::BytecodeForWideOperands(Bytecode bytecode) {
switch (bytecode) {
case Bytecode::kLoadICSloppy:
return Bytecode::kLoadICSloppyWide;
case Bytecode::kLoadICStrict:
return Bytecode::kLoadICStrictWide;
case Bytecode::kKeyedLoadICSloppy:
return Bytecode::kKeyedLoadICSloppyWide;
case Bytecode::kKeyedLoadICStrict:
return Bytecode::kKeyedLoadICStrictWide;
case Bytecode::kStoreICSloppy:
return Bytecode::kStoreICSloppyWide;
case Bytecode::kStoreICStrict:
return Bytecode::kStoreICStrictWide;
case Bytecode::kKeyedStoreICSloppy:
return Bytecode::kKeyedStoreICSloppyWide;
case Bytecode::kKeyedStoreICStrict:
return Bytecode::kKeyedStoreICStrictWide;
case Bytecode::kLdaGlobalSloppy:
return Bytecode::kLdaGlobalSloppyWide;
case Bytecode::kLdaGlobalStrict:
return Bytecode::kLdaGlobalStrictWide;
case Bytecode::kStaGlobalSloppy:
return Bytecode::kStaGlobalSloppyWide;
case Bytecode::kStaGlobalStrict:
return Bytecode::kStaGlobalStrictWide;
default:
UNREACHABLE();
return static_cast<Bytecode>(-1);
}
}
// static
Bytecode BytecodeArrayBuilder::BytecodeForLoadIC(LanguageMode language_mode) {
switch (language_mode) {
......@@ -1106,6 +1166,12 @@ bool BytecodeArrayBuilder::FitsInIdx16Operand(int value) {
}
// static
bool BytecodeArrayBuilder::FitsInIdx16Operand(size_t value) {
return value <= static_cast<size_t>(kMaxUInt16);
}
TemporaryRegisterScope::TemporaryRegisterScope(BytecodeArrayBuilder* builder)
: builder_(builder),
allocated_(builder->zone()),
......
......@@ -211,6 +211,7 @@ class BytecodeArrayBuilder {
static Bytecode BytecodeForBinaryOperation(Token::Value op);
static Bytecode BytecodeForCountOperation(Token::Value op);
static Bytecode BytecodeForCompareOperation(Token::Value op);
static Bytecode BytecodeForWideOperands(Bytecode bytecode);
static Bytecode BytecodeForLoadIC(LanguageMode language_mode);
static Bytecode BytecodeForKeyedLoadIC(LanguageMode language_mode);
static Bytecode BytecodeForStoreIC(LanguageMode language_mode);
......@@ -224,6 +225,7 @@ class BytecodeArrayBuilder {
static bool FitsInIdx8Operand(size_t value);
static bool FitsInImm8Operand(int value);
static bool FitsInIdx16Operand(int value);
static bool FitsInIdx16Operand(size_t value);
static Bytecode GetJumpWithConstantOperand(Bytecode jump_with_smi8_operand);
......
......@@ -36,18 +36,23 @@ namespace interpreter {
/* Loading the accumulator */ \
V(LdaZero, OperandType::kNone) \
V(LdaSmi8, OperandType::kImm8) \
V(LdaConstant, OperandType::kIdx8) \
V(LdaUndefined, OperandType::kNone) \
V(LdaNull, OperandType::kNone) \
V(LdaTheHole, OperandType::kNone) \
V(LdaTrue, OperandType::kNone) \
V(LdaFalse, OperandType::kNone) \
V(LdaConstant, OperandType::kIdx8) \
V(LdaConstantWide, OperandType::kIdx16) \
\
/* Globals */ \
V(LdaGlobalSloppy, OperandType::kIdx8, OperandType::kIdx8) \
V(LdaGlobalStrict, OperandType::kIdx8, OperandType::kIdx8) \
V(LdaGlobalSloppyWide, OperandType::kIdx16, OperandType::kIdx16) \
V(LdaGlobalStrictWide, OperandType::kIdx16, OperandType::kIdx16) \
V(StaGlobalSloppy, OperandType::kIdx8, OperandType::kIdx8) \
V(StaGlobalStrict, OperandType::kIdx8, OperandType::kIdx8) \
V(StaGlobalSloppyWide, OperandType::kIdx16, OperandType::kIdx16) \
V(StaGlobalStrictWide, OperandType::kIdx16, OperandType::kIdx16) \
\
/* Context operations */ \
V(PushContext, OperandType::kReg8) \
......@@ -64,6 +69,13 @@ namespace interpreter {
V(LoadICStrict, OperandType::kReg8, OperandType::kIdx8, OperandType::kIdx8) \
V(KeyedLoadICSloppy, OperandType::kReg8, OperandType::kIdx8) \
V(KeyedLoadICStrict, OperandType::kReg8, OperandType::kIdx8) \
/* TODO(rmcilroy): Wide register operands too? */ \
V(LoadICSloppyWide, OperandType::kReg8, OperandType::kIdx16, \
OperandType::kIdx16) \
V(LoadICStrictWide, OperandType::kReg8, OperandType::kIdx16, \
OperandType::kIdx16) \
V(KeyedLoadICSloppyWide, OperandType::kReg8, OperandType::kIdx16) \
V(KeyedLoadICStrictWide, OperandType::kReg8, OperandType::kIdx16) \
\
/* StoreIC operations */ \
V(StoreICSloppy, OperandType::kReg8, OperandType::kIdx8, OperandType::kIdx8) \
......@@ -72,6 +84,15 @@ namespace interpreter {
OperandType::kIdx8) \
V(KeyedStoreICStrict, OperandType::kReg8, OperandType::kReg8, \
OperandType::kIdx8) \
/* TODO(rmcilroy): Wide register operands too? */ \
V(StoreICSloppyWide, OperandType::kReg8, OperandType::kIdx16, \
OperandType::kIdx16) \
V(StoreICStrictWide, OperandType::kReg8, OperandType::kIdx16, \
OperandType::kIdx16) \
V(KeyedStoreICSloppyWide, OperandType::kReg8, OperandType::kReg8, \
OperandType::kIdx16) \
V(KeyedStoreICStrictWide, OperandType::kReg8, OperandType::kReg8, \
OperandType::kIdx16) \
\
/* Binary Operators */ \
V(Add, OperandType::kReg8) \
......
This diff is collapsed.
......@@ -63,6 +63,9 @@ class Interpreter {
void DoCompareOp(Token::Value compare_op,
compiler::InterpreterAssembler* assembler);
// Generates code to load a constant from the constant pool.
void DoLoadConstant(compiler::InterpreterAssembler* assembler);
// Generates code to perform a global load via |ic|.
void DoLoadGlobal(Callable ic, compiler::InterpreterAssembler* assembler);
......
......@@ -308,21 +308,21 @@ TARGET_TEST_F(InterpreterAssemblerTest, BytecodeOperand) {
int offset = interpreter::Bytecodes::GetOperandOffset(bytecode, i);
switch (interpreter::Bytecodes::GetOperandType(bytecode, i)) {
case interpreter::OperandType::kCount8:
EXPECT_THAT(m.BytecodeOperandCount8(i), m.IsBytecodeOperand(offset));
EXPECT_THAT(m.BytecodeOperandCount(i), m.IsBytecodeOperand(offset));
break;
case interpreter::OperandType::kIdx8:
EXPECT_THAT(m.BytecodeOperandIdx8(i), m.IsBytecodeOperand(offset));
EXPECT_THAT(m.BytecodeOperandIdx(i), m.IsBytecodeOperand(offset));
break;
case interpreter::OperandType::kImm8:
EXPECT_THAT(m.BytecodeOperandImm8(i),
EXPECT_THAT(m.BytecodeOperandImm(i),
m.IsBytecodeOperandSignExtended(offset));
break;
case interpreter::OperandType::kReg8:
EXPECT_THAT(m.BytecodeOperandReg8(i),
EXPECT_THAT(m.BytecodeOperandReg(i),
m.IsBytecodeOperandSignExtended(offset));
break;
case interpreter::OperandType::kIdx16:
EXPECT_THAT(m.BytecodeOperandIdx16(i),
EXPECT_THAT(m.BytecodeOperandIdx(i),
m.IsBytecodeOperandShort(offset));
break;
case interpreter::OperandType::kNone:
......
......@@ -49,6 +49,12 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
.StoreGlobal(0, 1, LanguageMode::SLOPPY)
.StoreGlobal(0, 1, LanguageMode::STRICT);
// Emit wide global load / store operations.
builder.LoadGlobal(0, 1024, LanguageMode::SLOPPY)
.LoadGlobal(1024, 1, LanguageMode::STRICT)
.StoreGlobal(0, 1024, LanguageMode::SLOPPY)
.StoreGlobal(1024, 1, LanguageMode::STRICT);
// Emit context operations.
builder.PushContext(reg);
builder.PopContext(reg);
......@@ -65,6 +71,16 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
.StoreNamedProperty(reg, 0, 0, LanguageMode::STRICT)
.StoreKeyedProperty(reg, reg, 0, LanguageMode::STRICT);
// Emit wide load / store property operations.
builder.LoadNamedProperty(reg, 2056, 0, LanguageMode::SLOPPY)
.LoadKeyedProperty(reg, 2056, LanguageMode::SLOPPY)
.StoreNamedProperty(reg, 0, 2056, LanguageMode::SLOPPY)
.StoreKeyedProperty(reg, reg, 2056, LanguageMode::SLOPPY)
.LoadNamedProperty(reg, 2056, 0, LanguageMode::STRICT)
.LoadKeyedProperty(reg, 2056, LanguageMode::STRICT)
.StoreNamedProperty(reg, 0, 2056, LanguageMode::STRICT)
.StoreKeyedProperty(reg, reg, 2056, LanguageMode::STRICT);
// Emit closure operations.
builder.CreateClosure(NOT_TENURED);
......@@ -160,6 +176,13 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
builder.ForInPrepare(reg).ForInDone(reg).ForInNext(reg, reg);
// Wide constant pool loads
for (int i = 0; i < 256; i++) {
// Emit junk in constant pool to force wide constant pool index.
builder.GetConstantPoolEntry(handle(Smi::FromInt(i), isolate()));
}
builder.LoadLiteral(Smi::FromInt(20000000));
builder.Return();
// Generate BytecodeArray.
......
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