[turbofan] Avoid embedding type feedback vector into code.

R=bmeurer@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#29216}
This commit is contained in:
mstarzinger 2015-06-23 01:27:16 -07:00 committed by Commit bot
parent 6c6a238004
commit 4ab2a18094
3 changed files with 47 additions and 31 deletions

View File

@ -483,16 +483,6 @@ Node* AstGraphBuilder::GetFunctionClosure() {
}
Node* AstGraphBuilder::GetFeedbackVector() {
if (!feedback_vector_.is_set()) {
Node* vector =
jsgraph()->Constant(handle(info()->shared_info()->feedback_vector()));
feedback_vector_.set(vector);
}
return feedback_vector_.get();
}
void AstGraphBuilder::CreateFunctionContext(bool constant_context) {
function_context_.set(constant_context
? jsgraph()->HeapConstant(info()->context())
@ -3297,7 +3287,7 @@ Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
uint32_t check_bitset = ComputeBitsetForDynamicGlobal(variable);
const Operator* op = javascript()->LoadDynamicGlobal(
name, check_bitset, feedback, contextual_mode);
value = NewNode(op, GetFeedbackVector(), current_context());
value = NewNode(op, BuildLoadFeedbackVector(), current_context());
states.AddToNode(value, bailout_id, combine);
} else if (mode == DYNAMIC_LOCAL) {
Variable* local = variable->local_if_not_shadowed();
@ -3321,7 +3311,7 @@ Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
uint32_t check_bitset = DynamicGlobalAccess::kFullCheckRequired;
const Operator* op = javascript()->LoadDynamicGlobal(
name, check_bitset, feedback, contextual_mode);
value = NewNode(op, GetFeedbackVector(), current_context());
value = NewNode(op, BuildLoadFeedbackVector(), current_context());
states.AddToNode(value, bailout_id, combine);
}
return value;
@ -3495,8 +3485,8 @@ static inline Node* Record(JSTypeFeedbackTable* js_type_feedback, Node* node,
Node* AstGraphBuilder::BuildKeyedLoad(Node* object, Node* key,
const VectorSlotPair& feedback) {
const Operator* op = javascript()->LoadProperty(feedback);
return Record(js_type_feedback_,
NewNode(op, object, key, GetFeedbackVector()), feedback.slot());
Node* node = NewNode(op, object, key, BuildLoadFeedbackVector());
return Record(js_type_feedback_, node, feedback.slot());
}
@ -3505,8 +3495,8 @@ Node* AstGraphBuilder::BuildNamedLoad(Node* object, Handle<Name> name,
ContextualMode mode) {
const Operator* op =
javascript()->LoadNamed(MakeUnique(name), feedback, mode);
return Record(js_type_feedback_, NewNode(op, object, GetFeedbackVector()),
feedback.slot());
Node* node = NewNode(op, object, BuildLoadFeedbackVector());
return Record(js_type_feedback_, node, feedback.slot());
}
@ -3514,7 +3504,8 @@ Node* AstGraphBuilder::BuildKeyedStore(Node* object, Node* key, Node* value,
const VectorSlotPair& feedback,
TypeFeedbackId id) {
const Operator* op = javascript()->StoreProperty(language_mode(), feedback);
return Record(js_type_feedback_, NewNode(op, object, key, value), id);
Node* node = NewNode(op, object, key, value);
return Record(js_type_feedback_, node, id);
}
@ -3524,7 +3515,8 @@ Node* AstGraphBuilder::BuildNamedStore(Node* object, Handle<Name> name,
TypeFeedbackId id) {
const Operator* op =
javascript()->StoreNamed(language_mode(), MakeUnique(name), feedback);
return Record(js_type_feedback_, NewNode(op, object, value), id);
Node* node = NewNode(op, object, value);
return Record(js_type_feedback_, node, id);
}
@ -3533,8 +3525,8 @@ Node* AstGraphBuilder::BuildNamedSuperLoad(Node* receiver, Node* home_object,
const VectorSlotPair& feedback) {
Node* name_node = jsgraph()->Constant(name);
const Operator* op = javascript()->CallRuntime(Runtime::kLoadFromSuper, 3);
Node* value = NewNode(op, receiver, home_object, name_node);
return Record(js_type_feedback_, value, feedback.slot());
Node* node = NewNode(op, receiver, home_object, name_node);
return Record(js_type_feedback_, node, feedback.slot());
}
@ -3543,8 +3535,8 @@ Node* AstGraphBuilder::BuildKeyedSuperLoad(Node* receiver, Node* home_object,
const VectorSlotPair& feedback) {
const Operator* op =
javascript()->CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
Node* value = NewNode(op, receiver, home_object, key);
return Record(js_type_feedback_, value, feedback.slot());
Node* node = NewNode(op, receiver, home_object, key);
return Record(js_type_feedback_, node, feedback.slot());
}
@ -3555,8 +3547,8 @@ Node* AstGraphBuilder::BuildKeyedSuperStore(Node* receiver, Node* home_object,
? Runtime::kStoreKeyedToSuper_Strict
: Runtime::kStoreKeyedToSuper_Sloppy;
const Operator* op = javascript()->CallRuntime(function_id, 4);
Node* result = NewNode(op, receiver, home_object, key, value);
return Record(js_type_feedback_, result, id);
Node* node = NewNode(op, receiver, home_object, key, value);
return Record(js_type_feedback_, node, id);
}
@ -3568,8 +3560,8 @@ Node* AstGraphBuilder::BuildNamedSuperStore(Node* receiver, Node* home_object,
? Runtime::kStoreToSuper_Strict
: Runtime::kStoreToSuper_Sloppy;
const Operator* op = javascript()->CallRuntime(function_id, 4);
Node* result = NewNode(op, receiver, home_object, name_node, value);
return Record(js_type_feedback_, result, id);
Node* node = NewNode(op, receiver, home_object, name_node, value);
return Record(js_type_feedback_, node, id);
}
@ -3579,6 +3571,13 @@ Node* AstGraphBuilder::BuildLoadObjectField(Node* object, int offset) {
}
Node* AstGraphBuilder::BuildLoadImmutableObjectField(Node* object, int offset) {
return graph()->NewNode(jsgraph()->machine()->Load(kMachAnyTagged), object,
jsgraph()->IntPtrConstant(offset - kHeapObjectTag),
graph()->start(), graph()->start());
}
Node* AstGraphBuilder::BuildLoadBuiltinsObject() {
Node* global = BuildLoadGlobalObject();
Node* builtins =
@ -3602,6 +3601,19 @@ Node* AstGraphBuilder::BuildLoadGlobalProxy() {
}
Node* AstGraphBuilder::BuildLoadFeedbackVector() {
if (!feedback_vector_.is_set()) {
Node* closure = GetFunctionClosure();
Node* shared = BuildLoadImmutableObjectField(
closure, JSFunction::kSharedFunctionInfoOffset);
Node* vector = BuildLoadImmutableObjectField(
shared, SharedFunctionInfo::kFeedbackVectorOffset);
feedback_vector_.set(vector);
}
return feedback_vector_.get();
}
Node* AstGraphBuilder::BuildLoadExternal(ExternalReference reference,
MachineType type) {
return NewNode(jsgraph()->machine()->Load(type),

View File

@ -88,7 +88,6 @@ class AstGraphBuilder : public AstVisitor {
// Nodes representing values in the activation record.
SetOncePointer<Node> function_closure_;
SetOncePointer<Node> function_context_;
SetOncePointer<Node> feedback_vector_;
// Tracks how many try-blocks are currently entered.
int try_catch_nesting_level_;
@ -98,6 +97,9 @@ class AstGraphBuilder : public AstVisitor {
int input_buffer_size_;
Node** input_buffer_;
// Optimization to cache loaded feedback vector.
SetOncePointer<Node> feedback_vector_;
// Control nodes that exit the function body.
ZoneVector<Node*> exit_controls_;
@ -155,9 +157,6 @@ class AstGraphBuilder : public AstVisitor {
Node* GetFunctionClosureForContext();
Node* GetFunctionClosure();
// Get or create the node that represents the functions type feedback vector.
Node* GetFeedbackVector();
// Node creation helpers.
Node* NewNode(const Operator* op, bool incomplete = false) {
return MakeNode(op, 0, static_cast<Node**>(NULL), incomplete);
@ -312,8 +311,11 @@ class AstGraphBuilder : public AstVisitor {
Node* BuildLoadBuiltinsObject();
Node* BuildLoadGlobalObject();
Node* BuildLoadGlobalProxy();
Node* BuildLoadClosure();
Node* BuildLoadFeedbackVector();
// Builder for accessing a (potentially immutable) object field.
Node* BuildLoadObjectField(Node* object, int offset);
Node* BuildLoadImmutableObjectField(Node* object, int offset);
// Builders for accessing external references.
Node* BuildLoadExternal(ExternalReference ref, MachineType type);

View File

@ -242,6 +242,7 @@ TEST(ContextLoadedFromActivation) {
i::Handle<i::Object> ofun = v8::Utils::OpenHandle(*value);
i::Handle<i::JSFunction> jsfun = Handle<JSFunction>::cast(ofun);
jsfun->set_code(T.function->code());
jsfun->set_shared(T.function->shared());
context->Global()->Set(v8_str("foo"), v8::Utils::ToLocal(jsfun));
CompileRun("var x = 24;");
ExpectInt32("foo();", 24);
@ -263,6 +264,7 @@ TEST(BuiltinLoadedFromActivation) {
i::Handle<i::Object> ofun = v8::Utils::OpenHandle(*value);
i::Handle<i::JSFunction> jsfun = Handle<JSFunction>::cast(ofun);
jsfun->set_code(T.function->code());
jsfun->set_shared(T.function->shared());
context->Global()->Set(v8_str("foo"), v8::Utils::ToLocal(jsfun));
CompileRun("var x = 24;");
ExpectObject("foo()", context->Global());