Reviewers: Sven Panne,
Description:
Implement non-generic stores for object literals.
This uses the type feedback already present for computed value stores
into object literals to generate optimized stores in Crankshaft, thus
avoiding unnecessary generic stores with side effects.
[email protected]
Please review this at https://chromiumcodereview.appspot.com/9692036/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/ast.h
M src/ast.cc
M src/hydrogen.h
M src/hydrogen.cc
M src/type-info.h
M src/type-info.cc
Index: src/ast.cc
diff --git a/src/ast.cc b/src/ast.cc
index
239e5d0ffe4475a2e885962a9a36832de23a8f54..666637b958ad747c0f39b5d69e1954832978a54c
100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -602,6 +602,14 @@ void
CompareOperation::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
}
+void ObjectLiteral::Property::RecordTypeFeedback(TypeFeedbackOracle*
oracle) {
+ is_monomorphic_ = oracle->ObjectLiteralStoreIsMonomorphic(this);
+ if (is_monomorphic_) {
+ receiver_type_ = oracle->GetObjectLiteralStoreMap(this);
+ }
+}
+
+
//
----------------------------------------------------------------------------
// Implementation of AstVisitor
Index: src/ast.h
diff --git a/src/ast.h b/src/ast.h
index
09864885e93e486b323b5d07bdc607a0256aae5a..78531bb4553f322e32f0d7c96708023be2189d0e
100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -1320,6 +1320,11 @@ class ObjectLiteral: public MaterializedLiteral {
Expression* value() { return value_; }
Kind kind() { return kind_; }
+ // Type feedback information.
+ void RecordTypeFeedback(TypeFeedbackOracle* oracle);
+ bool IsMonomorphic() { return is_monomorphic_; }
+ Handle<Map> GetReceiverType() { return receiver_type_; }
+
bool IsCompileTimeValue();
void set_emit_store(bool emit_store);
@@ -1336,6 +1341,8 @@ class ObjectLiteral: public MaterializedLiteral {
Expression* value_;
Kind kind_;
bool emit_store_;
+ bool is_monomorphic_;
+ Handle<Map> receiver_type_;
};
DECLARE_NODE_TYPE(ObjectLiteral)
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index
6a7b6098cb8537d747f2ce674e41e56fdd0f0c7c..943d50511b8b5948eaa76ded3a46431011ae822b
100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -3738,18 +3738,13 @@ void
HGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
case ObjectLiteral::Property::COMPUTED:
if (key->handle()->IsSymbol()) {
if (property->emit_store()) {
+ property->RecordTypeFeedback(oracle());
CHECK_ALIVE(VisitForValue(value));
HValue* value = Pop();
Handle<String> name = Handle<String>::cast(key->handle());
- HStoreNamedGeneric* store =
- new(zone()) HStoreNamedGeneric(
- context,
- literal,
- name,
- value,
- function_strict_mode_flag());
+ HInstruction* store = BuildStoreNamed(literal, value,
property);
AddInstruction(store);
- AddSimulate(key->id());
+ if (store->HasObservableSideEffects()) AddSimulate(key->id());
} else {
CHECK_ALIVE(VisitForEffect(value));
}
@@ -3954,6 +3949,25 @@ HInstruction*
HGraphBuilder::BuildStoreNamedGeneric(HValue* object,
HInstruction* HGraphBuilder::BuildStoreNamed(HValue* object,
HValue* value,
+ ObjectLiteral::Property*
prop) {
+ Literal* key = prop->key()->AsLiteral();
+ Handle<String> name = Handle<String>::cast(key->handle());
+ ASSERT(!name.is_null());
+
+ LookupResult lookup(isolate());
+ Handle<Map> type = prop->GetReceiverType();
+ bool is_monomorphic = prop->IsMonomorphic() &&
+ ComputeStoredField(type, name, &lookup);
+
+ return is_monomorphic
+ ? BuildStoreNamedField(object, name, value, type, &lookup,
+ true) // Needs smi and map check.
+ : BuildStoreNamedGeneric(object, name, value);
+}
+
+
+HInstruction* HGraphBuilder::BuildStoreNamed(HValue* object,
+ HValue* value,
Expression* expr) {
Property* prop = (expr->AsProperty() != NULL)
? expr->AsProperty()
Index: src/hydrogen.h
diff --git a/src/hydrogen.h b/src/hydrogen.h
index
b0d67ebb66c61f1aa8b790ddd392bd23edb5430c..cb39609f3d9e0d86fa0a489387503670c406b16d
100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -1077,6 +1077,9 @@ class HGraphBuilder: public AstVisitor {
HInstruction* BuildStoreNamed(HValue* object,
HValue* value,
Expression* expr);
+ HInstruction* BuildStoreNamed(HValue* object,
+ HValue* value,
+ ObjectLiteral::Property* prop);
HInstruction* BuildStoreNamedField(HValue* object,
Handle<String> name,
HValue* value,
Index: src/type-info.cc
diff --git a/src/type-info.cc b/src/type-info.cc
index
fa479b2e515b5c811b30c67bae9ce4c3fd4c9e09..926043719d97bf1ee2557a498e306add317c8597
100644
--- a/src/type-info.cc
+++ b/src/type-info.cc
@@ -154,6 +154,13 @@ bool TypeFeedbackOracle::CallNewIsMonomorphic(CallNew*
expr) {
}
+bool TypeFeedbackOracle::ObjectLiteralStoreIsMonomorphic(
+ ObjectLiteral::Property* prop) {
+ Handle<Object> map_or_code = GetInfo(prop->key()->id());
+ return map_or_code->IsMap();
+}
+
+
bool TypeFeedbackOracle::IsForInFastCase(ForInStatement* stmt) {
Handle<Object> value = GetInfo(stmt->PrepareId());
return value->IsSmi() &&
@@ -268,6 +275,13 @@ Handle<JSFunction>
TypeFeedbackOracle::GetCallNewTarget(CallNew* expr) {
}
+Handle<Map> TypeFeedbackOracle::GetObjectLiteralStoreMap(
+ ObjectLiteral::Property* prop) {
+ ASSERT(ObjectLiteralStoreIsMonomorphic(prop));
+ return Handle<Map>::cast(GetInfo(prop->key()->id()));
+}
+
+
bool TypeFeedbackOracle::LoadIsBuiltin(Property* expr, Builtins::Name id) {
return *GetInfo(expr->id()) ==
isolate_->builtins()->builtin(id);
Index: src/type-info.h
diff --git a/src/type-info.h b/src/type-info.h
index
84ec51d97567dc4b7ec6665913985546d9711e0d..2e2ce10f960f7f9007b47d65ca1d86db51da519d
100644
--- a/src/type-info.h
+++ b/src/type-info.h
@@ -29,6 +29,7 @@
#define V8_TYPE_INFO_H_
#include "allocation.h"
+#include "ast.h"
#include "globals.h"
#include "zone-inl.h"
@@ -243,6 +244,7 @@ class TypeFeedbackOracle BASE_EMBEDDED {
bool StoreIsMegamorphicWithTypeInfo(Expression* expr);
bool CallIsMonomorphic(Call* expr);
bool CallNewIsMonomorphic(CallNew* expr);
+ bool ObjectLiteralStoreIsMonomorphic(ObjectLiteral::Property* prop);
bool IsForInFastCase(ForInStatement* expr);
@@ -272,6 +274,8 @@ class TypeFeedbackOracle BASE_EMBEDDED {
Handle<JSFunction> GetCallTarget(Call* expr);
Handle<JSFunction> GetCallNewTarget(CallNew* expr);
+ Handle<Map> GetObjectLiteralStoreMap(ObjectLiteral::Property* prop);
+
bool LoadIsBuiltin(Property* expr, Builtins::Name id);
// TODO(1571) We can't use ToBooleanStub::Types as the return value
because
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev