Commit c0c214da authored by rmcilroy's avatar rmcilroy Committed by Commit bot

[Interpreter] Add support for loading from / storing to outer context variables.

Adds support for loading from and storing to outer context
variables. Also adds support for declaring functions on contexts and
locals. Finally, fixes a couple of issues with StaContextSlot where
we weren't emitting the write barrier and therefore would crash in the
GC.

Also added code so that --print-bytecode will output the
function name before the bytecodes, and replaces MachineType with StoreRepresentation in RawMachineAssembler::Store and updates tests.

BUG=v8:4280
LOG=N

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

Cr-Commit-Position: refs/heads/master@{#31584}
parent 2a4f5a64
...@@ -125,8 +125,9 @@ Node* InterpreterAssembler::LoadRegister(Node* reg_index) { ...@@ -125,8 +125,9 @@ Node* InterpreterAssembler::LoadRegister(Node* reg_index) {
Node* InterpreterAssembler::StoreRegister(Node* value, Node* reg_index) { Node* InterpreterAssembler::StoreRegister(Node* value, Node* reg_index) {
return raw_assembler_->Store(kMachAnyTagged, RegisterFileRawPointer(), return raw_assembler_->Store(
RegisterFrameOffset(reg_index), value); StoreRepresentation(kMachAnyTagged, kNoWriteBarrier),
RegisterFileRawPointer(), RegisterFrameOffset(reg_index), value);
} }
...@@ -316,7 +317,9 @@ Node* InterpreterAssembler::StoreContextSlot(Node* context, Node* slot_index, ...@@ -316,7 +317,9 @@ Node* InterpreterAssembler::StoreContextSlot(Node* context, Node* slot_index,
Node* offset = Node* offset =
IntPtrAdd(WordShl(slot_index, kPointerSizeLog2), IntPtrAdd(WordShl(slot_index, kPointerSizeLog2),
Int32Constant(Context::kHeaderSize - kHeapObjectTag)); Int32Constant(Context::kHeaderSize - kHeapObjectTag));
return raw_assembler_->Store(kMachAnyTagged, context, offset, value); return raw_assembler_->Store(
StoreRepresentation(kMachAnyTagged, kFullWriteBarrier), context, offset,
value);
} }
......
...@@ -126,12 +126,12 @@ class RawMachineAssembler { ...@@ -126,12 +126,12 @@ class RawMachineAssembler {
return AddNode(machine()->Load(rep), base, index, graph()->start(), return AddNode(machine()->Load(rep), base, index, graph()->start(),
graph()->start()); graph()->start());
} }
Node* Store(MachineType rep, Node* base, Node* value) { Node* Store(StoreRepresentation rep, Node* base, Node* value) {
return Store(rep, base, IntPtrConstant(0), value); return Store(rep, base, IntPtrConstant(0), value);
} }
Node* Store(MachineType rep, Node* base, Node* index, Node* value) { Node* Store(StoreRepresentation rep, Node* base, Node* index, Node* value) {
return AddNode(machine()->Store(StoreRepresentation(rep, kNoWriteBarrier)), return AddNode(machine()->Store(rep), base, index, value, graph()->start(),
base, index, value, graph()->start(), graph()->start()); graph()->start());
} }
// Arithmetic Operations. // Arithmetic Operations.
...@@ -486,7 +486,7 @@ class RawMachineAssembler { ...@@ -486,7 +486,7 @@ class RawMachineAssembler {
Node* LoadFromPointer(void* address, MachineType rep, int32_t offset = 0) { Node* LoadFromPointer(void* address, MachineType rep, int32_t offset = 0) {
return Load(rep, PointerConstant(address), Int32Constant(offset)); return Load(rep, PointerConstant(address), Int32Constant(offset));
} }
Node* StoreToPointer(void* address, MachineType rep, Node* node) { Node* StoreToPointer(void* address, StoreRepresentation rep, Node* node) {
return Store(rep, PointerConstant(address), node); return Store(rep, PointerConstant(address), node);
} }
Node* StringConstant(const char* string) { Node* StringConstant(const char* string) {
......
...@@ -43,10 +43,14 @@ class BytecodeGenerator::ContextScope BASE_EMBEDDED { ...@@ -43,10 +43,14 @@ class BytecodeGenerator::ContextScope BASE_EMBEDDED {
generator_->set_execution_context(outer_); generator_->set_execution_context(outer_);
} }
// Returns the execution context for the given |scope| if it is a function // Returns the depth of the given |scope| for the current execution context.
// local execution context, otherwise returns nullptr. int ContextChainDepth(Scope* scope) {
ContextScope* Previous(Scope* scope) { return scope_->ContextChainLength(scope);
int depth = scope_->ContextChainLength(scope); }
// Returns the execution context at |depth| in the current context chain if it
// is a function local execution context, otherwise returns nullptr.
ContextScope* Previous(int depth) {
if (depth > depth_) { if (depth > depth_) {
return nullptr; return nullptr;
} }
...@@ -414,8 +418,18 @@ void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) { ...@@ -414,8 +418,18 @@ void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
break; break;
} }
case VariableLocation::PARAMETER: case VariableLocation::PARAMETER:
case VariableLocation::LOCAL: case VariableLocation::LOCAL: {
case VariableLocation::CONTEXT: VisitForAccumulatorValue(decl->fun());
VisitVariableAssignment(variable, FeedbackVectorSlot::Invalid());
break;
}
case VariableLocation::CONTEXT: {
DCHECK_EQ(0, execution_context()->ContextChainDepth(variable->scope()));
VisitForAccumulatorValue(decl->fun());
builder()->StoreContextSlot(execution_context()->reg(),
variable->index());
break;
}
case VariableLocation::LOOKUP: case VariableLocation::LOOKUP:
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
...@@ -981,13 +995,27 @@ void BytecodeGenerator::VisitVariableLoad(Variable* variable, ...@@ -981,13 +995,27 @@ void BytecodeGenerator::VisitVariableLoad(Variable* variable,
break; break;
} }
case VariableLocation::CONTEXT: { case VariableLocation::CONTEXT: {
ContextScope* context = execution_context()->Previous(variable->scope()); int depth = execution_context()->ContextChainDepth(variable->scope());
ContextScope* context = execution_context()->Previous(depth);
Register context_reg;
if (context) { if (context) {
builder()->LoadContextSlot(context->reg(), variable->index()); context_reg = context->reg();
execution_result()->SetResultInAccumulator();
} else { } else {
UNIMPLEMENTED(); context_reg = execution_result()->NewRegister();
// Walk the context chain to find the context at the given depth.
// TODO(rmcilroy): Perform this work in a bytecode handler once we have
// a generic mechanism for performing jumps in interpreter.cc.
builder()
->LoadAccumulatorWithRegister(execution_context()->reg())
.StoreAccumulatorInRegister(context_reg);
for (int i = 0; i < depth; ++i) {
builder()
->LoadContextSlot(context_reg, Context::PREVIOUS_INDEX)
.StoreAccumulatorInRegister(context_reg);
}
} }
builder()->LoadContextSlot(context_reg, variable->index());
execution_result()->SetResultInAccumulator();
// TODO(rmcilroy): Perform check for uninitialized legacy const, const and // TODO(rmcilroy): Perform check for uninitialized legacy const, const and
// let variables. // let variables.
break; break;
...@@ -1039,12 +1067,29 @@ void BytecodeGenerator::VisitVariableAssignment(Variable* variable, ...@@ -1039,12 +1067,29 @@ void BytecodeGenerator::VisitVariableAssignment(Variable* variable,
} }
case VariableLocation::CONTEXT: { case VariableLocation::CONTEXT: {
// TODO(rmcilroy): support const mode initialization. // TODO(rmcilroy): support const mode initialization.
ContextScope* context = execution_context()->Previous(variable->scope()); int depth = execution_context()->ContextChainDepth(variable->scope());
ContextScope* context = execution_context()->Previous(depth);
Register context_reg;
if (context) { if (context) {
builder()->StoreContextSlot(context->reg(), variable->index()); context_reg = context->reg();
} else { } else {
UNIMPLEMENTED(); Register value_temp = execution_result()->NewRegister();
context_reg = execution_result()->NewRegister();
// Walk the context chain to find the context at the given depth.
// TODO(rmcilroy): Perform this work in a bytecode handler once we have
// a generic mechanism for performing jumps in interpreter.cc.
builder()
->StoreAccumulatorInRegister(value_temp)
.LoadAccumulatorWithRegister(execution_context()->reg())
.StoreAccumulatorInRegister(context_reg);
for (int i = 0; i < depth; ++i) {
builder()
->LoadContextSlot(context_reg, Context::PREVIOUS_INDEX)
.StoreAccumulatorInRegister(context_reg);
}
builder()->LoadAccumulatorWithRegister(value_temp);
} }
builder()->StoreContextSlot(context_reg, variable->index());
break; break;
} }
case VariableLocation::LOOKUP: case VariableLocation::LOOKUP:
......
...@@ -63,7 +63,10 @@ bool Interpreter::MakeBytecode(CompilationInfo* info) { ...@@ -63,7 +63,10 @@ bool Interpreter::MakeBytecode(CompilationInfo* info) {
info->EnsureFeedbackVector(); info->EnsureFeedbackVector();
Handle<BytecodeArray> bytecodes = generator.MakeBytecode(info); Handle<BytecodeArray> bytecodes = generator.MakeBytecode(info);
if (FLAG_print_bytecode) { if (FLAG_print_bytecode) {
bytecodes->Print(); OFStream os(stdout);
os << "Function: " << info->GetDebugName().get() << std::endl;
bytecodes->Print(os);
os << std::flush;
} }
info->SetBytecodeArray(bytecodes); info->SetBytecodeArray(bytecodes);
......
...@@ -36,6 +36,12 @@ inline MachineType MachineTypeForC() { ...@@ -36,6 +36,12 @@ inline MachineType MachineTypeForC() {
return kMachAnyTagged; return kMachAnyTagged;
} }
template <typename T>
inline StoreRepresentation StoreRepresentationForC(
WriteBarrierKind write_barrier_kind) {
return StoreRepresentation(MachineTypeForC<T>(), write_barrier_kind);
}
#define DECLARE_TEMPLATE_SPECIALIZATION(ctype, mtype) \ #define DECLARE_TEMPLATE_SPECIALIZATION(ctype, mtype) \
template <> \ template <> \
inline MachineType MachineTypeForC<ctype>() { \ inline MachineType MachineTypeForC<ctype>() { \
......
...@@ -110,7 +110,8 @@ class BinopTester { ...@@ -110,7 +110,8 @@ class BinopTester {
void AddReturn(Node* val) { void AddReturn(Node* val) {
if (use_result_buffer) { if (use_result_buffer) {
T->Store(rep, T->PointerConstant(&result), T->Int32Constant(0), val); T->Store(StoreRepresentation(rep, kNoWriteBarrier),
T->PointerConstant(&result), T->Int32Constant(0), val);
T->Return(T->Int32Constant(CHECK_VALUE)); T->Return(T->Int32Constant(CHECK_VALUE));
} else { } else {
T->Return(val); T->Return(val);
......
This diff is collapsed.
...@@ -361,7 +361,8 @@ class ArgsBuffer { ...@@ -361,7 +361,8 @@ class ArgsBuffer {
Node* StoreOutput(RawMachineAssembler& raw, Node* value) { Node* StoreOutput(RawMachineAssembler& raw, Node* value) {
Node* base = raw.PointerConstant(&output); Node* base = raw.PointerConstant(&output);
Node* offset = raw.Int32Constant(0); Node* offset = raw.Int32Constant(0);
return raw.Store(MachineTypeForC<CType>(), base, offset, value); return raw.Store(StoreRepresentationForC<CType>(kNoWriteBarrier), base,
offset, value);
} }
// Computes the next set of inputs by updating the {input} array. // Computes the next set of inputs by updating the {input} array.
...@@ -573,7 +574,8 @@ static void CopyTwentyInt32(CallDescriptor* desc) { ...@@ -573,7 +574,8 @@ static void CopyTwentyInt32(CallDescriptor* desc) {
Node* base = raw.PointerConstant(output); Node* base = raw.PointerConstant(output);
for (int i = 0; i < kNumParams; i++) { for (int i = 0; i < kNumParams; i++) {
Node* offset = raw.Int32Constant(i * sizeof(int32_t)); Node* offset = raw.Int32Constant(i * sizeof(int32_t));
raw.Store(kMachInt32, base, offset, raw.Parameter(i)); raw.Store(StoreRepresentation(kMachInt32, kNoWriteBarrier), base, offset,
raw.Parameter(i));
} }
raw.Return(raw.Int32Constant(42)); raw.Return(raw.Int32Constant(42));
inner = CompileGraph("CopyTwentyInt32", desc, &graph, raw.Export()); inner = CompileGraph("CopyTwentyInt32", desc, &graph, raw.Export());
...@@ -1141,7 +1143,8 @@ void MixedParamTest(int start) { ...@@ -1141,7 +1143,8 @@ void MixedParamTest(int start) {
} }
Node* call = raw.CallN(desc, target, args); Node* call = raw.CallN(desc, target, args);
Node* store = raw.StoreToPointer(output, sig->GetReturn(), call); StoreRepresentation store_rep(sig->GetReturn(), kNoWriteBarrier);
Node* store = raw.StoreToPointer(output, store_rep, call);
USE(store); USE(store);
expected_ret = static_cast<int32_t>(constant); expected_ret = static_cast<int32_t>(constant);
raw.Return(raw.Int32Constant(expected_ret)); raw.Return(raw.Int32Constant(expected_ret));
......
...@@ -35,7 +35,6 @@ class BytecodeGeneratorHelper { ...@@ -35,7 +35,6 @@ class BytecodeGeneratorHelper {
Isolate* isolate() { return CcTest::i_isolate(); } Isolate* isolate() { return CcTest::i_isolate(); }
Factory* factory() { return CcTest::i_isolate()->factory(); } Factory* factory() { return CcTest::i_isolate()->factory(); }
Handle<BytecodeArray> MakeTopLevelBytecode(const char* source) { Handle<BytecodeArray> MakeTopLevelBytecode(const char* source) {
const char* old_ignition_filter = i::FLAG_ignition_filter; const char* old_ignition_filter = i::FLAG_ignition_filter;
i::FLAG_ignition_filter = "*"; i::FLAG_ignition_filter = "*";
...@@ -45,7 +44,6 @@ class BytecodeGeneratorHelper { ...@@ -45,7 +44,6 @@ class BytecodeGeneratorHelper {
return handle(js_function->shared()->bytecode_array(), CcTest::i_isolate()); return handle(js_function->shared()->bytecode_array(), CcTest::i_isolate());
} }
Handle<BytecodeArray> MakeBytecode(const char* script, Handle<BytecodeArray> MakeBytecode(const char* script,
const char* function_name) { const char* function_name) {
CompileRun(script); CompileRun(script);
...@@ -56,7 +54,6 @@ class BytecodeGeneratorHelper { ...@@ -56,7 +54,6 @@ class BytecodeGeneratorHelper {
return handle(js_function->shared()->bytecode_array(), CcTest::i_isolate()); return handle(js_function->shared()->bytecode_array(), CcTest::i_isolate());
} }
Handle<BytecodeArray> MakeBytecodeForFunctionBody(const char* body) { Handle<BytecodeArray> MakeBytecodeForFunctionBody(const char* body) {
ScopedVector<char> program(1024); ScopedVector<char> program(1024);
SNPrintF(program, "function %s() { %s }\n%s();", kFunctionName, body, SNPrintF(program, "function %s() { %s }\n%s();", kFunctionName, body,
...@@ -69,6 +66,17 @@ class BytecodeGeneratorHelper { ...@@ -69,6 +66,17 @@ class BytecodeGeneratorHelper {
SNPrintF(program, "%s\n%s();", function, kFunctionName); SNPrintF(program, "%s\n%s();", function, kFunctionName);
return MakeBytecode(program.start(), kFunctionName); return MakeBytecode(program.start(), kFunctionName);
} }
Handle<BytecodeArray> MakeBytecodeForFunctionNoFilter(const char* function) {
const char* old_ignition_filter = i::FLAG_ignition_filter;
i::FLAG_ignition_filter = "*";
ScopedVector<char> program(1024);
SNPrintF(program, "%s\n%s();", function, kFunctionName);
Handle<BytecodeArray> return_val =
MakeBytecode(program.start(), kFunctionName);
i::FLAG_ignition_filter = old_ignition_filter;
return return_val;
}
}; };
...@@ -2909,6 +2917,69 @@ TEST(ContextParameters) { ...@@ -2909,6 +2917,69 @@ TEST(ContextParameters) {
} }
TEST(OuterContextVariables) {
InitializedHandleScope handle_scope;
BytecodeGeneratorHelper helper;
int context = Register::function_context().index();
int first_context_slot = Context::MIN_CONTEXT_SLOTS;
ExpectedSnippet<InstanceType> snippets[] = {
{"function Outer() {"
" var outerVar = 1;"
" function Inner(innerArg) {"
" this.innerFunc = function() { return outerVar * innerArg; }"
" }"
" this.getInnerFunc = function() { return new Inner(1).innerFunc; }"
"}"
"var f = new Outer().getInnerFunc();",
2 * kPointerSize,
1,
20,
{
B(Ldar), R(context), //
B(Star), R(0), //
B(LdaContextSlot), R(0), U8(Context::PREVIOUS_INDEX), //
B(Star), R(0), //
B(LdaContextSlot), R(0), U8(first_context_slot), //
B(Star), R(1), //
B(LdaContextSlot), R(context), U8(first_context_slot), //
B(Mul), R(1), //
B(Return), //
}},
{"function Outer() {"
" var outerVar = 1;"
" function Inner(innerArg) {"
" this.innerFunc = function() { outerVar = innerArg; }"
" }"
" this.getInnerFunc = function() { return new Inner(1).innerFunc; }"
"}"
"var f = new Outer().getInnerFunc();",
2 * kPointerSize,
1,
21,
{
B(LdaContextSlot), R(context), U8(first_context_slot), //
B(Star), R(0), //
B(Ldar), R(context), //
B(Star), R(1), //
B(LdaContextSlot), R(1), U8(Context::PREVIOUS_INDEX), //
B(Star), R(1), //
B(Ldar), R(0), //
B(StaContextSlot), R(1), U8(first_context_slot), //
B(LdaUndefined), //
B(Return), //
}},
};
for (size_t i = 0; i < arraysize(snippets); i++) {
Handle<BytecodeArray> bytecode_array =
helper.MakeBytecodeForFunctionNoFilter(snippets[i].code_snippet);
CheckBytecodeArrayEqual(snippets[i], bytecode_array);
}
}
TEST(CountOperators) { TEST(CountOperators) {
InitializedHandleScope handle_scope; InitializedHandleScope handle_scope;
BytecodeGeneratorHelper helper; BytecodeGeneratorHelper helper;
......
...@@ -58,7 +58,8 @@ class InterpreterTester { ...@@ -58,7 +58,8 @@ class InterpreterTester {
public: public:
InterpreterTester(Isolate* isolate, const char* source, InterpreterTester(Isolate* isolate, const char* source,
MaybeHandle<BytecodeArray> bytecode, MaybeHandle<BytecodeArray> bytecode,
MaybeHandle<TypeFeedbackVector> feedback_vector) MaybeHandle<TypeFeedbackVector> feedback_vector,
const char* filter)
: isolate_(isolate), : isolate_(isolate),
source_(source), source_(source),
bytecode_(bytecode), bytecode_(bytecode),
...@@ -70,7 +71,7 @@ class InterpreterTester { ...@@ -70,7 +71,7 @@ class InterpreterTester {
// Set ignition filter flag via SetFlagsFromString to avoid double-free // Set ignition filter flag via SetFlagsFromString to avoid double-free
// (or potential leak with StrDup() based on ownership confusion). // (or potential leak with StrDup() based on ownership confusion).
ScopedVector<char> ignition_filter(64); ScopedVector<char> ignition_filter(64);
SNPrintF(ignition_filter, "--ignition-filter=%s", kFunctionName); SNPrintF(ignition_filter, "--ignition-filter=%s", filter);
FlagList::SetFlagsFromString(ignition_filter.start(), FlagList::SetFlagsFromString(ignition_filter.start(),
ignition_filter.length()); ignition_filter.length());
// Ensure handler table is generated. // Ensure handler table is generated.
...@@ -79,13 +80,16 @@ class InterpreterTester { ...@@ -79,13 +80,16 @@ class InterpreterTester {
InterpreterTester(Isolate* isolate, Handle<BytecodeArray> bytecode, InterpreterTester(Isolate* isolate, Handle<BytecodeArray> bytecode,
MaybeHandle<TypeFeedbackVector> feedback_vector = MaybeHandle<TypeFeedbackVector> feedback_vector =
MaybeHandle<TypeFeedbackVector>()) MaybeHandle<TypeFeedbackVector>(),
: InterpreterTester(isolate, nullptr, bytecode, feedback_vector) {} const char* filter = kFunctionName)
: InterpreterTester(isolate, nullptr, bytecode, feedback_vector, filter) {
}
InterpreterTester(Isolate* isolate, const char* source) InterpreterTester(Isolate* isolate, const char* source,
const char* filter = kFunctionName)
: InterpreterTester(isolate, source, MaybeHandle<BytecodeArray>(), : InterpreterTester(isolate, source, MaybeHandle<BytecodeArray>(),
MaybeHandle<TypeFeedbackVector>()) {} MaybeHandle<TypeFeedbackVector>(), filter) {}
virtual ~InterpreterTester() {} virtual ~InterpreterTester() {}
...@@ -1919,6 +1923,39 @@ TEST(InterpreterContextParameters) { ...@@ -1919,6 +1923,39 @@ TEST(InterpreterContextParameters) {
} }
TEST(InterpreterOuterContextVariables) {
HandleAndZoneScope handles;
i::Isolate* isolate = handles.main_isolate();
std::pair<const char*, Handle<Object>> context_vars[2] = {
std::make_pair("return outerVar * innerArg;",
handle(Smi::FromInt(200), isolate)),
std::make_pair("outerVar = innerArg; return outerVar",
handle(Smi::FromInt(20), isolate)),
};
std::string header(
"function Outer() {"
" var outerVar = 10;"
" function Inner(innerArg) {"
" this.innerFunc = function() { ");
std::string footer(
" }}"
" this.getInnerFunc = function() { return new Inner(20).innerFunc; }"
"}"
"var f = new Outer().getInnerFunc();");
for (size_t i = 0; i < arraysize(context_vars); i++) {
std::string source = header + context_vars[i].first + footer;
InterpreterTester tester(handles.main_isolate(), source.c_str(), "*");
auto callable = tester.GetCallable<>();
Handle<i::Object> return_value = callable().ToHandleChecked();
CHECK(return_value->SameValue(*context_vars[i].second));
}
}
TEST(InterpreterComma) { TEST(InterpreterComma) {
HandleAndZoneScope handles; HandleAndZoneScope handles;
i::Isolate* isolate = handles.main_isolate(); i::Isolate* isolate = handles.main_isolate();
......
...@@ -1320,7 +1320,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) { ...@@ -1320,7 +1320,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) {
TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) { TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
const MemoryAccess memacc = GetParam(); const MemoryAccess memacc = GetParam();
StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type); StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2)); StoreRepresentation store_rep(memacc.type, kNoWriteBarrier);
m.Store(store_rep, m.Parameter(0), m.Parameter(1), m.Parameter(2));
m.Return(m.Int32Constant(0)); m.Return(m.Int32Constant(0));
Stream s = m.Build(); Stream s = m.Build();
ASSERT_EQ(1U, s.size()); ASSERT_EQ(1U, s.size());
...@@ -1335,8 +1336,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) { ...@@ -1335,8 +1336,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) {
const MemoryAccess memacc = GetParam(); const MemoryAccess memacc = GetParam();
TRACED_FOREACH(int32_t, index, memacc.immediates) { TRACED_FOREACH(int32_t, index, memacc.immediates) {
StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type); StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), StoreRepresentation store_rep(memacc.type, kNoWriteBarrier);
m.Parameter(1)); m.Store(store_rep, m.Parameter(0), m.Int32Constant(index), m.Parameter(1));
m.Return(m.Int32Constant(0)); m.Return(m.Int32Constant(0));
Stream s = m.Build(); Stream s = m.Build();
ASSERT_EQ(1U, s.size()); ASSERT_EQ(1U, s.size());
......
...@@ -2156,7 +2156,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) { ...@@ -2156,7 +2156,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) {
TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) { TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
const MemoryAccess memacc = GetParam(); const MemoryAccess memacc = GetParam();
StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type); StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2)); StoreRepresentation store_rep(memacc.type, kNoWriteBarrier);
m.Store(store_rep, m.Parameter(0), m.Parameter(1), m.Parameter(2));
m.Return(m.Int32Constant(0)); m.Return(m.Int32Constant(0));
Stream s = m.Build(); Stream s = m.Build();
ASSERT_EQ(1U, s.size()); ASSERT_EQ(1U, s.size());
...@@ -2171,8 +2172,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) { ...@@ -2171,8 +2172,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) {
const MemoryAccess memacc = GetParam(); const MemoryAccess memacc = GetParam();
TRACED_FOREACH(int32_t, index, memacc.immediates) { TRACED_FOREACH(int32_t, index, memacc.immediates) {
StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type); StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), StoreRepresentation store_rep(memacc.type, kNoWriteBarrier);
m.Parameter(1)); m.Store(store_rep, m.Parameter(0), m.Int32Constant(index), m.Parameter(1));
m.Return(m.Int32Constant(0)); m.Return(m.Int32Constant(0));
Stream s = m.Build(); Stream s = m.Build();
ASSERT_EQ(1U, s.size()); ASSERT_EQ(1U, s.size());
......
...@@ -249,7 +249,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) { ...@@ -249,7 +249,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) {
TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) { TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
const MemoryAccess memacc = GetParam(); const MemoryAccess memacc = GetParam();
StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type); StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2)); StoreRepresentation store_rep(memacc.type, kNoWriteBarrier);
m.Store(store_rep, m.Parameter(0), m.Parameter(1), m.Parameter(2));
m.Return(m.Int32Constant(0)); m.Return(m.Int32Constant(0));
Stream s = m.Build(); Stream s = m.Build();
ASSERT_EQ(1U, s.size()); ASSERT_EQ(1U, s.size());
...@@ -263,7 +264,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateBase) { ...@@ -263,7 +264,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateBase) {
const MemoryAccess memacc = GetParam(); const MemoryAccess memacc = GetParam();
TRACED_FOREACH(int32_t, base, kImmediates) { TRACED_FOREACH(int32_t, base, kImmediates) {
StreamBuilder m(this, kMachInt32, kMachInt32, memacc.type); StreamBuilder m(this, kMachInt32, kMachInt32, memacc.type);
m.Store(memacc.type, m.Int32Constant(base), m.Parameter(0), m.Parameter(1)); StoreRepresentation store_rep(memacc.type, kNoWriteBarrier);
m.Store(store_rep, m.Int32Constant(base), m.Parameter(0), m.Parameter(1));
m.Return(m.Int32Constant(0)); m.Return(m.Int32Constant(0));
Stream s = m.Build(); Stream s = m.Build();
ASSERT_EQ(1U, s.size()); ASSERT_EQ(1U, s.size());
...@@ -284,8 +286,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) { ...@@ -284,8 +286,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) {
const MemoryAccess memacc = GetParam(); const MemoryAccess memacc = GetParam();
TRACED_FOREACH(int32_t, index, kImmediates) { TRACED_FOREACH(int32_t, index, kImmediates) {
StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type); StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), StoreRepresentation store_rep(memacc.type, kNoWriteBarrier);
m.Parameter(1)); m.Store(store_rep, m.Parameter(0), m.Int32Constant(index), m.Parameter(1));
m.Return(m.Int32Constant(0)); m.Return(m.Int32Constant(0));
Stream s = m.Build(); Stream s = m.Build();
ASSERT_EQ(1U, s.size()); ASSERT_EQ(1U, s.size());
...@@ -319,7 +321,8 @@ class AddressingModeUnitTest : public InstructionSelectorTest { ...@@ -319,7 +321,8 @@ class AddressingModeUnitTest : public InstructionSelectorTest {
void Run(Node* base, Node* load_index, Node* store_index, void Run(Node* base, Node* load_index, Node* store_index,
AddressingMode mode) { AddressingMode mode) {
Node* load = m->Load(kMachInt32, base, load_index); Node* load = m->Load(kMachInt32, base, load_index);
m->Store(kMachInt32, base, store_index, load); m->Store(StoreRepresentation(kMachInt32, kNoWriteBarrier), base,
store_index, load);
m->Return(m->Int32Constant(0)); m->Return(m->Int32Constant(0));
Stream s = m->Build(); Stream s = m->Build();
ASSERT_EQ(2U, s.size()); ASSERT_EQ(2U, s.size());
......
...@@ -497,8 +497,9 @@ TARGET_TEST_F(InterpreterAssemblerTest, StoreContextSlot) { ...@@ -497,8 +497,9 @@ TARGET_TEST_F(InterpreterAssemblerTest, StoreContextSlot) {
Matcher<Node*> offset = Matcher<Node*> offset =
IsIntPtrAdd(IsWordShl(slot_index, IsInt32Constant(kPointerSizeLog2)), IsIntPtrAdd(IsWordShl(slot_index, IsInt32Constant(kPointerSizeLog2)),
IsInt32Constant(Context::kHeaderSize - kHeapObjectTag)); IsInt32Constant(Context::kHeaderSize - kHeapObjectTag));
EXPECT_THAT(store_context_slot, EXPECT_THAT(
m.IsStore(StoreRepresentation(kMachAnyTagged, kNoWriteBarrier), store_context_slot,
m.IsStore(StoreRepresentation(kMachAnyTagged, kFullWriteBarrier),
context, offset, value)); context, offset, value));
} }
} }
......
...@@ -646,7 +646,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) { ...@@ -646,7 +646,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) { TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
const MemoryAccess memacc = GetParam(); const MemoryAccess memacc = GetParam();
StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type); StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
m.Store(memacc.type, m.Parameter(0), m.Parameter(1)); StoreRepresentation store_rep(memacc.type, kNoWriteBarrier);
m.Store(store_rep, m.Parameter(0), m.Parameter(1));
m.Return(m.Int32Constant(0)); m.Return(m.Int32Constant(0));
Stream s = m.Build(); Stream s = m.Build();
ASSERT_EQ(1U, s.size()); ASSERT_EQ(1U, s.size());
...@@ -696,8 +697,8 @@ TEST_P(InstructionSelectorMemoryAccessImmTest, StoreWithImmediateIndex) { ...@@ -696,8 +697,8 @@ TEST_P(InstructionSelectorMemoryAccessImmTest, StoreWithImmediateIndex) {
const MemoryAccessImm memacc = GetParam(); const MemoryAccessImm memacc = GetParam();
TRACED_FOREACH(int32_t, index, memacc.immediates) { TRACED_FOREACH(int32_t, index, memacc.immediates) {
StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type); StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), StoreRepresentation store_rep(memacc.type, kNoWriteBarrier);
m.Parameter(1)); m.Store(store_rep, m.Parameter(0), m.Int32Constant(index), m.Parameter(1));
m.Return(m.Int32Constant(0)); m.Return(m.Int32Constant(0));
Stream s = m.Build(); Stream s = m.Build();
ASSERT_EQ(1U, s.size()); ASSERT_EQ(1U, s.size());
...@@ -748,8 +749,8 @@ TEST_P(InstructionSelectorMemoryAccessImmMoreThan16bitTest, ...@@ -748,8 +749,8 @@ TEST_P(InstructionSelectorMemoryAccessImmMoreThan16bitTest,
const MemoryAccessImm1 memacc = GetParam(); const MemoryAccessImm1 memacc = GetParam();
TRACED_FOREACH(int32_t, index, memacc.immediates) { TRACED_FOREACH(int32_t, index, memacc.immediates) {
StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type); StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), StoreRepresentation store_rep(memacc.type, kNoWriteBarrier);
m.Parameter(1)); m.Store(store_rep, m.Parameter(0), m.Int32Constant(index), m.Parameter(1));
m.Return(m.Int32Constant(0)); m.Return(m.Int32Constant(0));
Stream s = m.Build(); Stream s = m.Build();
ASSERT_EQ(2U, s.size()); ASSERT_EQ(2U, s.size());
......
...@@ -649,7 +649,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) { ...@@ -649,7 +649,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) { TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
const MemoryAccess memacc = GetParam(); const MemoryAccess memacc = GetParam();
StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type); StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
m.Store(memacc.type, m.Parameter(0), m.Parameter(1)); StoreRepresentation store_rep(memacc.type, kNoWriteBarrier);
m.Store(store_rep, m.Parameter(0), m.Parameter(1));
m.Return(m.Int32Constant(0)); m.Return(m.Int32Constant(0));
Stream s = m.Build(); Stream s = m.Build();
ASSERT_EQ(1U, s.size()); ASSERT_EQ(1U, s.size());
...@@ -697,8 +698,8 @@ TEST_P(InstructionSelectorMemoryAccessImmTest, StoreWithImmediateIndex) { ...@@ -697,8 +698,8 @@ TEST_P(InstructionSelectorMemoryAccessImmTest, StoreWithImmediateIndex) {
const MemoryAccessImm memacc = GetParam(); const MemoryAccessImm memacc = GetParam();
TRACED_FOREACH(int32_t, index, memacc.immediates) { TRACED_FOREACH(int32_t, index, memacc.immediates) {
StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type); StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), StoreRepresentation store_rep(memacc.type, kNoWriteBarrier);
m.Parameter(1)); m.Store(store_rep, m.Parameter(0), m.Int32Constant(index), m.Parameter(1));
m.Return(m.Int32Constant(0)); m.Return(m.Int32Constant(0));
Stream s = m.Build(); Stream s = m.Build();
ASSERT_EQ(1U, s.size()); ASSERT_EQ(1U, s.size());
...@@ -746,8 +747,8 @@ TEST_P(InstructionSelectorMemoryAccessImmMoreThan16bitTest, ...@@ -746,8 +747,8 @@ TEST_P(InstructionSelectorMemoryAccessImmMoreThan16bitTest,
const MemoryAccessImm1 memacc = GetParam(); const MemoryAccessImm1 memacc = GetParam();
TRACED_FOREACH(int32_t, index, memacc.immediates) { TRACED_FOREACH(int32_t, index, memacc.immediates) {
StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type); StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), StoreRepresentation store_rep(memacc.type, kNoWriteBarrier);
m.Parameter(1)); m.Store(store_rep, m.Parameter(0), m.Int32Constant(index), m.Parameter(1));
m.Return(m.Int32Constant(0)); m.Return(m.Int32Constant(0));
Stream s = m.Build(); Stream s = m.Build();
ASSERT_EQ(2U, s.size()); ASSERT_EQ(2U, s.size());
......
...@@ -124,7 +124,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) { ...@@ -124,7 +124,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) { TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
const MemoryAccess memacc = GetParam(); const MemoryAccess memacc = GetParam();
StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type); StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2)); StoreRepresentation store_rep(memacc.type, kNoWriteBarrier);
m.Store(store_rep, m.Parameter(0), m.Parameter(1), m.Parameter(2));
m.Return(m.Int32Constant(0)); m.Return(m.Int32Constant(0));
Stream s = m.Build(); Stream s = m.Build();
ASSERT_EQ(1U, s.size()); ASSERT_EQ(1U, s.size());
......
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