[turbofan] Switch message object manipulation to JSOperator.

This switches loading and storing of the message object within the
Isolate to use JavaScript operators built by the JSOperatorBuilder
instead of machine operators. This is a preparation for a stricter
representation selection for loads and stores.

R=jarin@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#31879}
This commit is contained in:
mstarzinger 2015-11-09 04:44:18 -08:00 committed by Commit bot
parent bddf8c9e08
commit 270be9351c
8 changed files with 67 additions and 51 deletions

View File

@ -1386,8 +1386,6 @@ void AstGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) {
void AstGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) {
TryCatchBuilder try_control(this);
ExternalReference message_object =
ExternalReference::address_of_pending_message_obj(isolate());
// Evaluate the try-block inside a control scope. This simulates a handler
// that is intercepting 'throw' control commands.
@ -1411,7 +1409,7 @@ void AstGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) {
// Clear message object as we enter the catch block.
Node* the_hole = jsgraph()->TheHoleConstant();
BuildStoreExternal(message_object, kMachAnyTagged, the_hole);
NewNode(javascript()->StoreMessage(), the_hole);
// Create a catch scope that binds the exception.
Node* exception = try_control.GetExceptionNode();
@ -1427,8 +1425,6 @@ void AstGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) {
void AstGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
TryFinallyBuilder try_control(this);
ExternalReference message_object =
ExternalReference::address_of_pending_message_obj(isolate());
// We keep a record of all paths that enter the finally-block to be able to
// dispatch to the correct continuation point after the statements in the
@ -1473,14 +1469,14 @@ void AstGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
// The result value, dispatch token and message is expected on the operand
// stack (this is in sync with FullCodeGenerator::EnterFinallyBlock).
Node* message = BuildLoadExternal(message_object, kMachAnyTagged);
Node* message = NewNode(javascript()->LoadMessage());
environment()->Push(token); // TODO(mstarzinger): Cook token!
environment()->Push(result);
environment()->Push(message);
// Clear message object as we enter the finally block.
Node* the_hole = jsgraph()->TheHoleConstant();
BuildStoreExternal(message_object, kMachAnyTagged, the_hole);
NewNode(javascript()->StoreMessage(), the_hole);
// Evaluate the finally-block.
Visit(stmt->finally_block());
@ -1491,7 +1487,7 @@ void AstGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
message = environment()->Pop();
result = environment()->Pop();
token = environment()->Pop(); // TODO(mstarzinger): Uncook token!
BuildStoreExternal(message_object, kMachAnyTagged, message);
NewNode(javascript()->StoreMessage(), message);
// Dynamic dispatch after the finally-block.
commands->ApplyDeferredCommands(token, result);
@ -3678,23 +3674,6 @@ Node* AstGraphBuilder::BuildLoadFeedbackVector() {
}
Node* AstGraphBuilder::BuildLoadExternal(ExternalReference reference,
MachineType type) {
return NewNode(jsgraph()->machine()->Load(type),
jsgraph()->ExternalConstant(reference),
jsgraph()->IntPtrConstant(0));
}
Node* AstGraphBuilder::BuildStoreExternal(ExternalReference reference,
MachineType type, Node* value) {
StoreRepresentation representation(type, kNoWriteBarrier);
return NewNode(jsgraph()->machine()->Store(representation),
jsgraph()->ExternalConstant(reference),
jsgraph()->IntPtrConstant(0), value);
}
Node* AstGraphBuilder::BuildToBoolean(Node* input) {
if (Node* node = TryFastToBoolean(input)) return node;
return NewNode(javascript()->ToBoolean(), input);

View File

@ -308,10 +308,6 @@ class AstGraphBuilder : public AstVisitor {
Node* BuildLoadObjectField(Node* object, int offset);
Node* BuildLoadImmutableObjectField(Node* object, int offset);
// Builders for accessing external references.
Node* BuildLoadExternal(ExternalReference ref, MachineType type);
Node* BuildStoreExternal(ExternalReference ref, MachineType type, Node* val);
// Builders for automatic type conversion.
Node* BuildToBoolean(Node* input);
Node* BuildToName(Node* input, BailoutId bailout_id);

View File

@ -772,6 +772,27 @@ void JSGenericLowering::LowerJSForInStep(Node* node) {
}
void JSGenericLowering::LowerJSLoadMessage(Node* node) {
ExternalReference message_address =
ExternalReference::address_of_pending_message_obj(isolate());
node->RemoveInput(NodeProperties::FirstContextIndex(node));
node->InsertInput(zone(), 0, jsgraph()->ExternalConstant(message_address));
node->InsertInput(zone(), 1, jsgraph()->IntPtrConstant(0));
NodeProperties::ChangeOp(node, machine()->Load(kMachAnyTagged));
}
void JSGenericLowering::LowerJSStoreMessage(Node* node) {
ExternalReference message_address =
ExternalReference::address_of_pending_message_obj(isolate());
node->RemoveInput(NodeProperties::FirstContextIndex(node));
node->InsertInput(zone(), 0, jsgraph()->ExternalConstant(message_address));
node->InsertInput(zone(), 1, jsgraph()->IntPtrConstant(0));
StoreRepresentation representation(kMachAnyTagged, kNoWriteBarrier);
NodeProperties::ChangeOp(node, machine()->Store(representation));
}
void JSGenericLowering::LowerJSYield(Node* node) { UNIMPLEMENTED(); }

View File

@ -351,28 +351,30 @@ const CreateClosureParameters& CreateClosureParametersOf(const Operator* op) {
}
#define CACHED_OP_LIST(V) \
V(Equal, Operator::kNoProperties, 2, 1) \
V(NotEqual, Operator::kNoProperties, 2, 1) \
V(StrictEqual, Operator::kNoThrow, 2, 1) \
V(StrictNotEqual, Operator::kNoThrow, 2, 1) \
V(UnaryNot, Operator::kEliminatable, 1, 1) \
V(ToBoolean, Operator::kEliminatable, 1, 1) \
V(ToNumber, Operator::kNoProperties, 1, 1) \
V(ToString, Operator::kNoProperties, 1, 1) \
V(ToName, Operator::kNoProperties, 1, 1) \
V(ToObject, Operator::kNoProperties, 1, 1) \
V(Yield, Operator::kNoProperties, 1, 1) \
V(Create, Operator::kEliminatable, 0, 1) \
V(HasProperty, Operator::kNoProperties, 2, 1) \
V(TypeOf, Operator::kEliminatable, 1, 1) \
V(InstanceOf, Operator::kNoProperties, 2, 1) \
V(ForInDone, Operator::kPure, 2, 1) \
V(ForInNext, Operator::kNoProperties, 4, 1) \
V(ForInPrepare, Operator::kNoProperties, 1, 3) \
V(ForInStep, Operator::kPure, 1, 1) \
V(StackCheck, Operator::kNoProperties, 0, 0) \
V(CreateWithContext, Operator::kNoProperties, 2, 1) \
#define CACHED_OP_LIST(V) \
V(Equal, Operator::kNoProperties, 2, 1) \
V(NotEqual, Operator::kNoProperties, 2, 1) \
V(StrictEqual, Operator::kNoThrow, 2, 1) \
V(StrictNotEqual, Operator::kNoThrow, 2, 1) \
V(UnaryNot, Operator::kEliminatable, 1, 1) \
V(ToBoolean, Operator::kEliminatable, 1, 1) \
V(ToNumber, Operator::kNoProperties, 1, 1) \
V(ToString, Operator::kNoProperties, 1, 1) \
V(ToName, Operator::kNoProperties, 1, 1) \
V(ToObject, Operator::kNoProperties, 1, 1) \
V(Yield, Operator::kNoProperties, 1, 1) \
V(Create, Operator::kEliminatable, 0, 1) \
V(HasProperty, Operator::kNoProperties, 2, 1) \
V(TypeOf, Operator::kEliminatable, 1, 1) \
V(InstanceOf, Operator::kNoProperties, 2, 1) \
V(ForInDone, Operator::kPure, 2, 1) \
V(ForInNext, Operator::kNoProperties, 4, 1) \
V(ForInPrepare, Operator::kNoProperties, 1, 3) \
V(ForInStep, Operator::kPure, 1, 1) \
V(LoadMessage, Operator::kNoThrow, 0, 1) \
V(StoreMessage, Operator::kNoThrow, 1, 0) \
V(StackCheck, Operator::kNoProperties, 0, 0) \
V(CreateWithContext, Operator::kNoProperties, 2, 1) \
V(CreateModuleContext, Operator::kNoProperties, 2, 1)

View File

@ -441,6 +441,9 @@ class JSOperatorBuilder final : public ZoneObject {
const Operator* ForInPrepare();
const Operator* ForInStep();
const Operator* LoadMessage();
const Operator* StoreMessage();
const Operator* StackCheck();
const Operator* CreateFunctionContext(int slot_count);

View File

@ -144,6 +144,8 @@
V(JSForInNext) \
V(JSForInPrepare) \
V(JSForInStep) \
V(JSLoadMessage) \
V(JSStoreMessage) \
V(JSYield) \
V(JSStackCheck)

View File

@ -1574,6 +1574,15 @@ Type* Typer::Visitor::TypeJSForInStep(Node* node) {
}
Type* Typer::Visitor::TypeJSLoadMessage(Node* node) { return Type::Any(); }
Type* Typer::Visitor::TypeJSStoreMessage(Node* node) {
UNREACHABLE();
return nullptr;
}
Type* Typer::Visitor::TypeJSStackCheck(Node* node) { return Type::Any(); }

View File

@ -602,6 +602,10 @@ void Verifier::Visitor::Check(Node* node) {
break;
}
case IrOpcode::kJSLoadMessage:
case IrOpcode::kJSStoreMessage:
break;
case IrOpcode::kJSStackCheck:
// Type is empty.
CheckNotTyped(node);