Commit 3d31d251 authored by mvstanton's avatar mvstanton Committed by Commit bot

[Turbofan]: generic lowering can use a constant vector

Since we are specializing on the native context, we don't have to load
the vector from the closure. For one thing, this reduces the machinery for
nodes that use a vector in their generic incarnation.

BUG=
R=mstarzinger@chromium.org

Review-Url: https://codereview.chromium.org/2529463002
Cr-Commit-Position: refs/heads/master@{#41221}
parent 2b96c9d7
......@@ -3537,7 +3537,7 @@ Node* AstGraphBuilder::BuildVariableAssignment(
Node* AstGraphBuilder::BuildKeyedLoad(Node* object, Node* key,
const VectorSlotPair& feedback) {
const Operator* op = javascript()->LoadProperty(feedback);
Node* node = NewNode(op, object, key, GetFunctionClosure());
Node* node = NewNode(op, object, key);
return node;
}
......@@ -3545,7 +3545,7 @@ Node* AstGraphBuilder::BuildKeyedLoad(Node* object, Node* key,
Node* AstGraphBuilder::BuildNamedLoad(Node* object, Handle<Name> name,
const VectorSlotPair& feedback) {
const Operator* op = javascript()->LoadNamed(name, feedback);
Node* node = NewNode(op, object, GetFunctionClosure());
Node* node = NewNode(op, object);
return node;
}
......@@ -3553,7 +3553,7 @@ Node* AstGraphBuilder::BuildNamedLoad(Node* object, Handle<Name> name,
Node* AstGraphBuilder::BuildKeyedStore(Node* object, Node* key, Node* value,
const VectorSlotPair& feedback) {
const Operator* op = javascript()->StoreProperty(language_mode(), feedback);
Node* node = NewNode(op, object, key, value, GetFunctionClosure());
Node* node = NewNode(op, object, key, value);
return node;
}
......@@ -3563,7 +3563,7 @@ Node* AstGraphBuilder::BuildNamedStore(Node* object, Handle<Name> name,
const VectorSlotPair& feedback) {
const Operator* op =
javascript()->StoreNamed(language_mode(), name, feedback);
Node* node = NewNode(op, object, value, GetFunctionClosure());
Node* node = NewNode(op, object, value);
return node;
}
......@@ -3614,7 +3614,7 @@ Node* AstGraphBuilder::BuildGlobalLoad(Handle<Name> name,
const VectorSlotPair& feedback,
TypeofMode typeof_mode) {
const Operator* op = javascript()->LoadGlobal(name, feedback, typeof_mode);
Node* node = NewNode(op, GetFunctionClosure());
Node* node = NewNode(op);
return node;
}
......@@ -3623,7 +3623,7 @@ Node* AstGraphBuilder::BuildGlobalStore(Handle<Name> name, Node* value,
const VectorSlotPair& feedback) {
const Operator* op =
javascript()->StoreGlobal(language_mode(), name, feedback);
Node* node = NewNode(op, value, GetFunctionClosure());
Node* node = NewNode(op, value);
return node;
}
......
......@@ -743,7 +743,7 @@ Node* BytecodeGraphBuilder::BuildLoadGlobal(Handle<Name> name,
DCHECK_EQ(FeedbackVectorSlotKind::LOAD_GLOBAL_IC,
feedback_vector()->GetKind(feedback.slot()));
const Operator* op = javascript()->LoadGlobal(name, feedback, typeof_mode);
return NewNode(op, GetFunctionClosure());
return NewNode(op);
}
void BytecodeGraphBuilder::VisitLdaGlobal() {
......@@ -775,7 +775,7 @@ void BytecodeGraphBuilder::BuildStoreGlobal(LanguageMode language_mode) {
Node* value = environment()->LookupAccumulator();
const Operator* op = javascript()->StoreGlobal(language_mode, name, feedback);
Node* node = NewNode(op, value, GetFunctionClosure());
Node* node = NewNode(op, value);
environment()->RecordAfterState(node, Environment::kAttachFrameState);
}
......@@ -1037,7 +1037,7 @@ void BytecodeGraphBuilder::VisitLdaNamedProperty() {
CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
const Operator* op = javascript()->LoadNamed(name, feedback);
Node* node = NewNode(op, object, GetFunctionClosure());
Node* node = NewNode(op, object);
environment()->BindAccumulator(node, Environment::kAttachFrameState);
}
......@@ -1050,7 +1050,7 @@ void BytecodeGraphBuilder::VisitLdaKeyedProperty() {
CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1));
const Operator* op = javascript()->LoadProperty(feedback);
Node* node = NewNode(op, object, key, GetFunctionClosure());
Node* node = NewNode(op, object, key);
environment()->BindAccumulator(node, Environment::kAttachFrameState);
}
......@@ -1065,7 +1065,7 @@ void BytecodeGraphBuilder::BuildNamedStore(LanguageMode language_mode) {
CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
const Operator* op = javascript()->StoreNamed(language_mode, name, feedback);
Node* node = NewNode(op, object, value, GetFunctionClosure());
Node* node = NewNode(op, object, value);
environment()->RecordAfterState(node, Environment::kAttachFrameState);
}
......@@ -1088,7 +1088,7 @@ void BytecodeGraphBuilder::BuildKeyedStore(LanguageMode language_mode) {
CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
const Operator* op = javascript()->StoreProperty(language_mode, feedback);
Node* node = NewNode(op, object, key, value, GetFunctionClosure());
Node* node = NewNode(op, object, key, value);
environment()->RecordAfterState(node, Environment::kAttachFrameState);
}
......
......@@ -153,76 +153,37 @@ void JSGenericLowering::LowerJSTypeOf(Node* node) {
void JSGenericLowering::LowerJSLoadProperty(Node* node) {
Node* closure = NodeProperties::GetValueInput(node, 2);
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
const PropertyAccess& p = PropertyAccessOf(node->op());
Callable callable = CodeFactory::KeyedLoadICInOptimizedCode(isolate());
// Load the type feedback vector from the closure.
Node* literals = effect = graph()->NewNode(
machine()->Load(MachineType::AnyTagged()), closure,
jsgraph()->IntPtrConstant(JSFunction::kLiteralsOffset - kHeapObjectTag),
effect, control);
Node* vector = effect = graph()->NewNode(
machine()->Load(MachineType::AnyTagged()), literals,
jsgraph()->IntPtrConstant(LiteralsArray::kFeedbackVectorOffset -
kHeapObjectTag),
effect, control);
Node* vector = jsgraph()->HeapConstant(p.feedback().vector());
node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
node->ReplaceInput(3, vector);
node->ReplaceInput(6, effect);
node->InsertInput(zone(), 3, vector);
ReplaceWithStubCall(node, callable, flags);
}
void JSGenericLowering::LowerJSLoadNamed(Node* node) {
Node* closure = NodeProperties::GetValueInput(node, 1);
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
NamedAccess const& p = NamedAccessOf(node->op());
Callable callable = CodeFactory::LoadICInOptimizedCode(isolate());
// Load the type feedback vector from the closure.
Node* literals = effect = graph()->NewNode(
machine()->Load(MachineType::AnyTagged()), closure,
jsgraph()->IntPtrConstant(JSFunction::kLiteralsOffset - kHeapObjectTag),
effect, control);
Node* vector = effect = graph()->NewNode(
machine()->Load(MachineType::AnyTagged()), literals,
jsgraph()->IntPtrConstant(LiteralsArray::kFeedbackVectorOffset -
kHeapObjectTag),
effect, control);
Node* vector = jsgraph()->HeapConstant(p.feedback().vector());
node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
node->ReplaceInput(3, vector);
node->ReplaceInput(6, effect);
node->InsertInput(zone(), 3, vector);
ReplaceWithStubCall(node, callable, flags);
}
void JSGenericLowering::LowerJSLoadGlobal(Node* node) {
Node* closure = NodeProperties::GetValueInput(node, 0);
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
const LoadGlobalParameters& p = LoadGlobalParametersOf(node->op());
Callable callable =
CodeFactory::LoadGlobalICInOptimizedCode(isolate(), p.typeof_mode());
// Load the type feedback vector from the closure.
Node* literals = effect = graph()->NewNode(
machine()->Load(MachineType::AnyTagged()), closure,
jsgraph()->IntPtrConstant(JSFunction::kLiteralsOffset - kHeapObjectTag),
effect, control);
Node* vector = effect = graph()->NewNode(
machine()->Load(MachineType::AnyTagged()), literals,
jsgraph()->IntPtrConstant(LiteralsArray::kFeedbackVectorOffset -
kHeapObjectTag),
effect, control);
Node* vector = jsgraph()->HeapConstant(p.feedback().vector());
node->InsertInput(zone(), 0, jsgraph()->HeapConstant(p.name()));
node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.feedback().index()));
node->ReplaceInput(2, vector);
node->ReplaceInput(5, effect);
node->InsertInput(zone(), 2, vector);
ReplaceWithStubCall(node, callable, flags);
}
......@@ -231,33 +192,20 @@ void JSGenericLowering::LowerJSStoreProperty(Node* node) {
Node* receiver = NodeProperties::GetValueInput(node, 0);
Node* key = NodeProperties::GetValueInput(node, 1);
Node* value = NodeProperties::GetValueInput(node, 2);
Node* closure = NodeProperties::GetValueInput(node, 3);
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
PropertyAccess const& p = PropertyAccessOf(node->op());
LanguageMode language_mode = p.language_mode();
Callable callable =
CodeFactory::KeyedStoreICInOptimizedCode(isolate(), language_mode);
// Load the type feedback vector from the closure.
Node* literals = effect = graph()->NewNode(
machine()->Load(MachineType::AnyTagged()), closure,
jsgraph()->IntPtrConstant(JSFunction::kLiteralsOffset - kHeapObjectTag),
effect, control);
Node* vector = effect = graph()->NewNode(
machine()->Load(MachineType::AnyTagged()), literals,
jsgraph()->IntPtrConstant(LiteralsArray::kFeedbackVectorOffset -
kHeapObjectTag),
effect, control);
Node* vector = jsgraph()->HeapConstant(p.feedback().vector());
typedef StoreWithVectorDescriptor Descriptor;
node->InsertInputs(zone(), 0, 1);
node->InsertInputs(zone(), 0, 2);
node->ReplaceInput(Descriptor::kReceiver, receiver);
node->ReplaceInput(Descriptor::kName, key);
node->ReplaceInput(Descriptor::kValue, value);
node->ReplaceInput(Descriptor::kSlot,
jsgraph()->SmiConstant(p.feedback().index()));
node->ReplaceInput(Descriptor::kVector, vector);
node->ReplaceInput(7, effect);
ReplaceWithStubCall(node, callable, flags);
}
......@@ -265,39 +213,25 @@ void JSGenericLowering::LowerJSStoreProperty(Node* node) {
void JSGenericLowering::LowerJSStoreNamed(Node* node) {
Node* receiver = NodeProperties::GetValueInput(node, 0);
Node* value = NodeProperties::GetValueInput(node, 1);
Node* closure = NodeProperties::GetValueInput(node, 2);
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
NamedAccess const& p = NamedAccessOf(node->op());
Callable callable =
CodeFactory::StoreICInOptimizedCode(isolate(), p.language_mode());
// Load the type feedback vector from the closure.
Node* literals = effect = graph()->NewNode(
machine()->Load(MachineType::AnyTagged()), closure,
jsgraph()->IntPtrConstant(JSFunction::kLiteralsOffset - kHeapObjectTag),
effect, control);
Node* vector = effect = graph()->NewNode(
machine()->Load(MachineType::AnyTagged()), literals,
jsgraph()->IntPtrConstant(LiteralsArray::kFeedbackVectorOffset -
kHeapObjectTag),
effect, control);
Node* vector = jsgraph()->HeapConstant(p.feedback().vector());
typedef StoreWithVectorDescriptor Descriptor;
node->InsertInputs(zone(), 0, 2);
node->InsertInputs(zone(), 0, 3);
node->ReplaceInput(Descriptor::kReceiver, receiver);
node->ReplaceInput(Descriptor::kName, jsgraph()->HeapConstant(p.name()));
node->ReplaceInput(Descriptor::kValue, value);
node->ReplaceInput(Descriptor::kSlot,
jsgraph()->SmiConstant(p.feedback().index()));
node->ReplaceInput(Descriptor::kVector, vector);
node->ReplaceInput(7, effect);
ReplaceWithStubCall(node, callable, flags);
}
void JSGenericLowering::LowerJSStoreGlobal(Node* node) {
Node* value = NodeProperties::GetValueInput(node, 0);
Node* closure = NodeProperties::GetValueInput(node, 1);
Node* context = NodeProperties::GetContextInput(node);
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
......@@ -305,16 +239,7 @@ void JSGenericLowering::LowerJSStoreGlobal(Node* node) {
const StoreGlobalParameters& p = StoreGlobalParametersOf(node->op());
Callable callable =
CodeFactory::StoreICInOptimizedCode(isolate(), p.language_mode());
// Load the type feedback vector from the closure.
Node* literals = effect = graph()->NewNode(
machine()->Load(MachineType::AnyTagged()), closure,
jsgraph()->IntPtrConstant(JSFunction::kLiteralsOffset - kHeapObjectTag),
effect, control);
Node* vector = effect = graph()->NewNode(
machine()->Load(MachineType::AnyTagged()), literals,
jsgraph()->IntPtrConstant(LiteralsArray::kFeedbackVectorOffset -
kHeapObjectTag),
effect, control);
Node* vector = jsgraph()->HeapConstant(p.feedback().vector());
// Load global object from the context.
Node* native_context = effect =
graph()->NewNode(machine()->Load(MachineType::AnyTagged()), context,
......@@ -326,7 +251,7 @@ void JSGenericLowering::LowerJSStoreGlobal(Node* node) {
jsgraph()->IntPtrConstant(Context::SlotOffset(Context::EXTENSION_INDEX)),
effect, control);
typedef StoreWithVectorDescriptor Descriptor;
node->InsertInputs(zone(), 0, 3);
node->InsertInputs(zone(), 0, 4);
node->ReplaceInput(Descriptor::kReceiver, global);
node->ReplaceInput(Descriptor::kName, jsgraph()->HeapConstant(p.name()));
node->ReplaceInput(Descriptor::kValue, value);
......
......@@ -663,7 +663,7 @@ const Operator* JSOperatorBuilder::LoadNamed(Handle<Name> name,
return new (zone()) Operator1<NamedAccess>( // --
IrOpcode::kJSLoadNamed, Operator::kNoProperties, // opcode
"JSLoadNamed", // name
2, 1, 1, 1, 1, 2, // counts
1, 1, 1, 1, 1, 2, // counts
access); // parameter
}
......@@ -673,7 +673,7 @@ const Operator* JSOperatorBuilder::LoadProperty(
return new (zone()) Operator1<PropertyAccess>( // --
IrOpcode::kJSLoadProperty, Operator::kNoProperties, // opcode
"JSLoadProperty", // name
3, 1, 1, 1, 1, 2, // counts
2, 1, 1, 1, 1, 2, // counts
access); // parameter
}
......@@ -700,7 +700,7 @@ const Operator* JSOperatorBuilder::StoreNamed(LanguageMode language_mode,
return new (zone()) Operator1<NamedAccess>( // --
IrOpcode::kJSStoreNamed, Operator::kNoProperties, // opcode
"JSStoreNamed", // name
3, 1, 1, 0, 1, 2, // counts
2, 1, 1, 0, 1, 2, // counts
access); // parameter
}
......@@ -711,7 +711,7 @@ const Operator* JSOperatorBuilder::StoreProperty(
return new (zone()) Operator1<PropertyAccess>( // --
IrOpcode::kJSStoreProperty, Operator::kNoProperties, // opcode
"JSStoreProperty", // name
4, 1, 1, 0, 1, 2, // counts
3, 1, 1, 0, 1, 2, // counts
access); // parameter
}
......@@ -732,7 +732,7 @@ const Operator* JSOperatorBuilder::LoadGlobal(const Handle<Name>& name,
return new (zone()) Operator1<LoadGlobalParameters>( // --
IrOpcode::kJSLoadGlobal, Operator::kNoProperties, // opcode
"JSLoadGlobal", // name
1, 1, 1, 1, 1, 2, // counts
0, 1, 1, 1, 1, 2, // counts
parameters); // parameter
}
......@@ -744,7 +744,7 @@ const Operator* JSOperatorBuilder::StoreGlobal(LanguageMode language_mode,
return new (zone()) Operator1<StoreGlobalParameters>( // --
IrOpcode::kJSStoreGlobal, Operator::kNoProperties, // opcode
"JSStoreGlobal", // name
2, 1, 1, 0, 1, 2, // counts
1, 1, 1, 0, 1, 2, // counts
parameters); // parameter
}
......
......@@ -14,11 +14,12 @@
#include "src/compiler/all-nodes.h"
#include "src/compiler/common-operator.h"
#include "src/compiler/graph.h"
#include "src/compiler/node.h"
#include "src/compiler/js-operator.h"
#include "src/compiler/node-properties.h"
#include "src/compiler/node.h"
#include "src/compiler/opcodes.h"
#include "src/compiler/operator.h"
#include "src/compiler/operator-properties.h"
#include "src/compiler/operator.h"
#include "src/compiler/schedule.h"
#include "src/compiler/simplified-operator.h"
#include "src/ostreams.h"
......@@ -590,14 +591,35 @@ void Verifier::Visitor::Check(Node* node) {
CheckTypeIs(node, Type::OtherObject());
break;
case IrOpcode::kJSLoadProperty:
// Type can be anything.
CheckTypeIs(node, Type::Any());
CHECK(PropertyAccessOf(node->op()).feedback().IsValid());
break;
case IrOpcode::kJSLoadNamed:
// Type can be anything.
CheckTypeIs(node, Type::Any());
CHECK(NamedAccessOf(node->op()).feedback().IsValid());
break;
case IrOpcode::kJSLoadGlobal:
// Type can be anything.
CheckTypeIs(node, Type::Any());
CHECK(LoadGlobalParametersOf(node->op()).feedback().IsValid());
break;
case IrOpcode::kJSStoreProperty:
// Type is empty.
CheckNotTyped(node);
CHECK(PropertyAccessOf(node->op()).feedback().IsValid());
break;
case IrOpcode::kJSStoreNamed:
// Type is empty.
CheckNotTyped(node);
CHECK(NamedAccessOf(node->op()).feedback().IsValid());
break;
case IrOpcode::kJSStoreGlobal:
// Type is empty.
CheckNotTyped(node);
CHECK(StoreGlobalParametersOf(node->op()).feedback().IsValid());
break;
case IrOpcode::kJSStoreDataPropertyInLiteral:
// Type is empty.
CheckNotTyped(node);
......
......@@ -580,13 +580,12 @@ TEST_F(JSTypedLoweringTest, JSLoadPropertyFromExternalTypedArray) {
Node* key = Parameter(
Type::Range(kMinInt / element_size, kMaxInt / element_size, zone()));
Node* base = HeapConstant(array);
Node* vector = UndefinedConstant();
Node* context = UndefinedConstant();
Node* effect = graph()->start();
Node* control = graph()->start();
Reduction r = Reduce(graph()->NewNode(javascript()->LoadProperty(feedback),
base, key, vector, context,
EmptyFrameState(), effect, control));
Reduction r =
Reduce(graph()->NewNode(javascript()->LoadProperty(feedback), base, key,
context, EmptyFrameState(), effect, control));
Matcher<Node*> offset_matcher =
element_size == 1
......@@ -622,13 +621,12 @@ TEST_F(JSTypedLoweringTest, JSLoadPropertyFromExternalTypedArrayWithSafeKey) {
if (min > max) std::swap(min, max);
Node* key = Parameter(Type::Range(min, max, zone()));
Node* base = HeapConstant(array);
Node* vector = UndefinedConstant();
Node* context = UndefinedConstant();
Node* effect = graph()->start();
Node* control = graph()->start();
Reduction r = Reduce(graph()->NewNode(javascript()->LoadProperty(feedback),
base, key, vector, context,
EmptyFrameState(), effect, control));
Reduction r =
Reduce(graph()->NewNode(javascript()->LoadProperty(feedback), base, key,
context, EmptyFrameState(), effect, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(
......@@ -660,13 +658,12 @@ TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArray) {
Node* base = HeapConstant(array);
Node* value =
Parameter(AccessBuilder::ForTypedArrayElement(type, true).type);
Node* vector = UndefinedConstant();
Node* context = UndefinedConstant();
Node* effect = graph()->start();
Node* control = graph()->start();
VectorSlotPair feedback;
const Operator* op = javascript()->StoreProperty(language_mode, feedback);
Node* node = graph()->NewNode(op, base, key, value, vector, context,
Node* node = graph()->NewNode(op, base, key, value, context,
EmptyFrameState(), effect, control);
Reduction r = Reduce(node);
......@@ -704,7 +701,6 @@ TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArrayWithConversion) {
Type::Range(kMinInt / element_size, kMaxInt / element_size, zone()));
Node* base = HeapConstant(array);
Node* value = Parameter(Type::Any());
Node* vector = UndefinedConstant();
Node* context = UndefinedConstant();
Node* effect = graph()->start();
Node* control = graph()->start();
......@@ -714,7 +710,7 @@ TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArrayWithConversion) {
EmptyFrameState(), effect, control);
VectorSlotPair feedback;
const Operator* op = javascript()->StoreProperty(language_mode, feedback);
Node* node = graph()->NewNode(op, base, key, value, vector, context,
Node* node = graph()->NewNode(op, base, key, value, context,
EmptyFrameState(), checkpoint, control);
Reduction r = Reduce(node);
......@@ -759,13 +755,12 @@ TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArrayWithSafeKey) {
Node* key = Parameter(Type::Range(min, max, zone()));
Node* base = HeapConstant(array);
Node* value = Parameter(access.type);
Node* vector = UndefinedConstant();
Node* context = UndefinedConstant();
Node* effect = graph()->start();
Node* control = graph()->start();
VectorSlotPair feedback;
const Operator* op = javascript()->StoreProperty(language_mode, feedback);
Node* node = graph()->NewNode(op, base, key, value, vector, context,
Node* node = graph()->NewNode(op, base, key, value, context,
EmptyFrameState(), effect, control);
Reduction r = Reduce(node);
......@@ -788,13 +783,12 @@ TEST_F(JSTypedLoweringTest, JSLoadNamedStringLength) {
VectorSlotPair feedback;
Handle<Name> name = factory()->length_string();
Node* const receiver = Parameter(Type::String(), 0);
Node* const vector = Parameter(Type::Internal(), 1);
Node* const context = UndefinedConstant();
Node* const effect = graph()->start();
Node* const control = graph()->start();
Reduction const r = Reduce(
graph()->NewNode(javascript()->LoadNamed(name, feedback), receiver,
vector, context, EmptyFrameState(), effect, control));
Reduction const r =
Reduce(graph()->NewNode(javascript()->LoadNamed(name, feedback), receiver,
context, EmptyFrameState(), effect, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsLoadField(AccessBuilder::ForStringLength(),
receiver, effect, control));
......
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