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) {
Node* InterpreterAssembler::StoreRegister(Node* value, Node* reg_index) {
return raw_assembler_->Store(kMachAnyTagged, RegisterFileRawPointer(),
RegisterFrameOffset(reg_index), value);
return raw_assembler_->Store(
StoreRepresentation(kMachAnyTagged, kNoWriteBarrier),
RegisterFileRawPointer(), RegisterFrameOffset(reg_index), value);
}
......@@ -316,7 +317,9 @@ Node* InterpreterAssembler::StoreContextSlot(Node* context, Node* slot_index,
Node* offset =
IntPtrAdd(WordShl(slot_index, kPointerSizeLog2),
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 {
return AddNode(machine()->Load(rep), base, index, 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);
}
Node* Store(MachineType rep, Node* base, Node* index, Node* value) {
return AddNode(machine()->Store(StoreRepresentation(rep, kNoWriteBarrier)),
base, index, value, graph()->start(), graph()->start());
Node* Store(StoreRepresentation rep, Node* base, Node* index, Node* value) {
return AddNode(machine()->Store(rep), base, index, value, graph()->start(),
graph()->start());
}
// Arithmetic Operations.
......@@ -486,7 +486,7 @@ class RawMachineAssembler {
Node* LoadFromPointer(void* address, MachineType rep, int32_t offset = 0) {
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);
}
Node* StringConstant(const char* string) {
......
......@@ -43,10 +43,14 @@ class BytecodeGenerator::ContextScope BASE_EMBEDDED {
generator_->set_execution_context(outer_);
}
// Returns the execution context for the given |scope| if it is a function
// local execution context, otherwise returns nullptr.
ContextScope* Previous(Scope* scope) {
int depth = scope_->ContextChainLength(scope);
// Returns the depth of the given |scope| for the current execution context.
int ContextChainDepth(Scope* scope) {
return 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_) {
return nullptr;
}
......@@ -414,8 +418,18 @@ void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
break;
}
case VariableLocation::PARAMETER:
case VariableLocation::LOCAL:
case VariableLocation::CONTEXT:
case VariableLocation::LOCAL: {
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:
UNIMPLEMENTED();
}
......@@ -981,13 +995,27 @@ void BytecodeGenerator::VisitVariableLoad(Variable* variable,
break;
}
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) {
builder()->LoadContextSlot(context->reg(), variable->index());
execution_result()->SetResultInAccumulator();
context_reg = context->reg();
} 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
// let variables.
break;
......@@ -1039,12 +1067,29 @@ void BytecodeGenerator::VisitVariableAssignment(Variable* variable,
}
case VariableLocation::CONTEXT: {
// 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) {
builder()->StoreContextSlot(context->reg(), variable->index());
context_reg = context->reg();
} 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;
}
case VariableLocation::LOOKUP:
......
......@@ -63,7 +63,10 @@ bool Interpreter::MakeBytecode(CompilationInfo* info) {
info->EnsureFeedbackVector();
Handle<BytecodeArray> bytecodes = generator.MakeBytecode(info);
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);
......
......@@ -36,6 +36,12 @@ inline MachineType MachineTypeForC() {
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) \
template <> \
inline MachineType MachineTypeForC<ctype>() { \
......
......@@ -110,7 +110,8 @@ class BinopTester {
void AddReturn(Node* val) {
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));
} else {
T->Return(val);
......
This diff is collapsed.
......@@ -361,7 +361,8 @@ class ArgsBuffer {
Node* StoreOutput(RawMachineAssembler& raw, Node* value) {
Node* base = raw.PointerConstant(&output);
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.
......@@ -573,7 +574,8 @@ static void CopyTwentyInt32(CallDescriptor* desc) {
Node* base = raw.PointerConstant(output);
for (int i = 0; i < kNumParams; i++) {
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));
inner = CompileGraph("CopyTwentyInt32", desc, &graph, raw.Export());
......@@ -1141,7 +1143,8 @@ void MixedParamTest(int start) {
}
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);
expected_ret = static_cast<int32_t>(constant);
raw.Return(raw.Int32Constant(expected_ret));
......
......@@ -35,7 +35,6 @@ class BytecodeGeneratorHelper {
Isolate* isolate() { return CcTest::i_isolate(); }
Factory* factory() { return CcTest::i_isolate()->factory(); }
Handle<BytecodeArray> MakeTopLevelBytecode(const char* source) {
const char* old_ignition_filter = i::FLAG_ignition_filter;
i::FLAG_ignition_filter = "*";
......@@ -45,7 +44,6 @@ class BytecodeGeneratorHelper {
return handle(js_function->shared()->bytecode_array(), CcTest::i_isolate());
}
Handle<BytecodeArray> MakeBytecode(const char* script,
const char* function_name) {
CompileRun(script);
......@@ -56,7 +54,6 @@ class BytecodeGeneratorHelper {
return handle(js_function->shared()->bytecode_array(), CcTest::i_isolate());
}
Handle<BytecodeArray> MakeBytecodeForFunctionBody(const char* body) {
ScopedVector<char> program(1024);
SNPrintF(program, "function %s() { %s }\n%s();", kFunctionName, body,
......@@ -69,6 +66,17 @@ class BytecodeGeneratorHelper {
SNPrintF(program, "%s\n%s();", function, 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) {
}
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) {
InitializedHandleScope handle_scope;
BytecodeGeneratorHelper helper;
......
......@@ -58,7 +58,8 @@ class InterpreterTester {
public:
InterpreterTester(Isolate* isolate, const char* source,
MaybeHandle<BytecodeArray> bytecode,
MaybeHandle<TypeFeedbackVector> feedback_vector)
MaybeHandle<TypeFeedbackVector> feedback_vector,
const char* filter)
: isolate_(isolate),
source_(source),
bytecode_(bytecode),
......@@ -70,7 +71,7 @@ class InterpreterTester {
// Set ignition filter flag via SetFlagsFromString to avoid double-free
// (or potential leak with StrDup() based on ownership confusion).
ScopedVector<char> ignition_filter(64);
SNPrintF(ignition_filter, "--ignition-filter=%s", kFunctionName);
SNPrintF(ignition_filter, "--ignition-filter=%s", filter);
FlagList::SetFlagsFromString(ignition_filter.start(),
ignition_filter.length());
// Ensure handler table is generated.
......@@ -79,13 +80,16 @@ class InterpreterTester {
InterpreterTester(Isolate* isolate, Handle<BytecodeArray> bytecode,
MaybeHandle<TypeFeedbackVector> feedback_vector =
MaybeHandle<TypeFeedbackVector>())
: InterpreterTester(isolate, nullptr, bytecode, feedback_vector) {}
MaybeHandle<TypeFeedbackVector>(),
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>(),
MaybeHandle<TypeFeedbackVector>()) {}
MaybeHandle<TypeFeedbackVector>(), filter) {}
virtual ~InterpreterTester() {}
......@@ -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) {
HandleAndZoneScope handles;
i::Isolate* isolate = handles.main_isolate();
......
......@@ -1320,7 +1320,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) {
TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
const MemoryAccess memacc = GetParam();
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));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
......@@ -1335,8 +1336,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) {
const MemoryAccess memacc = GetParam();
TRACED_FOREACH(int32_t, index, memacc.immediates) {
StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
m.Parameter(1));
StoreRepresentation store_rep(memacc.type, kNoWriteBarrier);
m.Store(store_rep, m.Parameter(0), m.Int32Constant(index), m.Parameter(1));
m.Return(m.Int32Constant(0));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
......
......@@ -2156,7 +2156,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) {
TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
const MemoryAccess memacc = GetParam();
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));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
......@@ -2171,8 +2172,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) {
const MemoryAccess memacc = GetParam();
TRACED_FOREACH(int32_t, index, memacc.immediates) {
StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
m.Parameter(1));
StoreRepresentation store_rep(memacc.type, kNoWriteBarrier);
m.Store(store_rep, m.Parameter(0), m.Int32Constant(index), m.Parameter(1));
m.Return(m.Int32Constant(0));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
......
......@@ -249,7 +249,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) {
TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
const MemoryAccess memacc = GetParam();
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));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
......@@ -263,7 +264,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateBase) {
const MemoryAccess memacc = GetParam();
TRACED_FOREACH(int32_t, base, kImmediates) {
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));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
......@@ -284,8 +286,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) {
const MemoryAccess memacc = GetParam();
TRACED_FOREACH(int32_t, index, kImmediates) {
StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
m.Parameter(1));
StoreRepresentation store_rep(memacc.type, kNoWriteBarrier);
m.Store(store_rep, m.Parameter(0), m.Int32Constant(index), m.Parameter(1));
m.Return(m.Int32Constant(0));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
......@@ -319,7 +321,8 @@ class AddressingModeUnitTest : public InstructionSelectorTest {
void Run(Node* base, Node* load_index, Node* store_index,
AddressingMode mode) {
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));
Stream s = m->Build();
ASSERT_EQ(2U, s.size());
......
......@@ -497,9 +497,10 @@ TARGET_TEST_F(InterpreterAssemblerTest, StoreContextSlot) {
Matcher<Node*> offset =
IsIntPtrAdd(IsWordShl(slot_index, IsInt32Constant(kPointerSizeLog2)),
IsInt32Constant(Context::kHeaderSize - kHeapObjectTag));
EXPECT_THAT(store_context_slot,
m.IsStore(StoreRepresentation(kMachAnyTagged, kNoWriteBarrier),
context, offset, value));
EXPECT_THAT(
store_context_slot,
m.IsStore(StoreRepresentation(kMachAnyTagged, kFullWriteBarrier),
context, offset, value));
}
}
......
......@@ -646,7 +646,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
const MemoryAccess memacc = GetParam();
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));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
......@@ -696,8 +697,8 @@ TEST_P(InstructionSelectorMemoryAccessImmTest, StoreWithImmediateIndex) {
const MemoryAccessImm memacc = GetParam();
TRACED_FOREACH(int32_t, index, memacc.immediates) {
StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
m.Parameter(1));
StoreRepresentation store_rep(memacc.type, kNoWriteBarrier);
m.Store(store_rep, m.Parameter(0), m.Int32Constant(index), m.Parameter(1));
m.Return(m.Int32Constant(0));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
......@@ -748,8 +749,8 @@ TEST_P(InstructionSelectorMemoryAccessImmMoreThan16bitTest,
const MemoryAccessImm1 memacc = GetParam();
TRACED_FOREACH(int32_t, index, memacc.immediates) {
StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
m.Parameter(1));
StoreRepresentation store_rep(memacc.type, kNoWriteBarrier);
m.Store(store_rep, m.Parameter(0), m.Int32Constant(index), m.Parameter(1));
m.Return(m.Int32Constant(0));
Stream s = m.Build();
ASSERT_EQ(2U, s.size());
......
......@@ -649,7 +649,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
const MemoryAccess memacc = GetParam();
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));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
......@@ -697,8 +698,8 @@ TEST_P(InstructionSelectorMemoryAccessImmTest, StoreWithImmediateIndex) {
const MemoryAccessImm memacc = GetParam();
TRACED_FOREACH(int32_t, index, memacc.immediates) {
StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
m.Parameter(1));
StoreRepresentation store_rep(memacc.type, kNoWriteBarrier);
m.Store(store_rep, m.Parameter(0), m.Int32Constant(index), m.Parameter(1));
m.Return(m.Int32Constant(0));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
......@@ -746,8 +747,8 @@ TEST_P(InstructionSelectorMemoryAccessImmMoreThan16bitTest,
const MemoryAccessImm1 memacc = GetParam();
TRACED_FOREACH(int32_t, index, memacc.immediates) {
StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
m.Parameter(1));
StoreRepresentation store_rep(memacc.type, kNoWriteBarrier);
m.Store(store_rep, m.Parameter(0), m.Int32Constant(index), m.Parameter(1));
m.Return(m.Int32Constant(0));
Stream s = m.Build();
ASSERT_EQ(2U, s.size());
......
......@@ -124,7 +124,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
const MemoryAccess memacc = GetParam();
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));
Stream s = m.Build();
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