Revision: 11023
Author: [email protected]
Date: Tue Mar 13 05:11:46 2012
Log: 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]
Review URL: https://chromiumcodereview.appspot.com/9692036
http://code.google.com/p/v8/source/detail?r=11023
Modified:
/branches/bleeding_edge/src/ast.cc
/branches/bleeding_edge/src/ast.h
/branches/bleeding_edge/src/hydrogen.cc
/branches/bleeding_edge/src/hydrogen.h
/branches/bleeding_edge/src/type-info.cc
/branches/bleeding_edge/src/type-info.h
=======================================
--- /branches/bleeding_edge/src/ast.cc Fri Mar 9 00:34:35 2012
+++ /branches/bleeding_edge/src/ast.cc Tue Mar 13 05:11:46 2012
@@ -600,6 +600,13 @@
ASSERT(compare_type_ == NONE);
}
}
+
+
+void ObjectLiteral::Property::RecordTypeFeedback(TypeFeedbackOracle*
oracle) {
+ receiver_type_ = oracle->ObjectLiteralStoreIsMonomorphic(this)
+ ? oracle->GetObjectLiteralStoreMap(this)
+ : Handle<Map>::null();
+}
//
----------------------------------------------------------------------------
=======================================
--- /branches/bleeding_edge/src/ast.h Fri Mar 9 00:34:35 2012
+++ /branches/bleeding_edge/src/ast.h Tue Mar 13 05:11:46 2012
@@ -1319,6 +1319,11 @@
Literal* key() { return key_; }
Expression* value() { return value_; }
Kind kind() { return kind_; }
+
+ // Type feedback information.
+ void RecordTypeFeedback(TypeFeedbackOracle* oracle);
+ bool IsMonomorphic() { return !receiver_type_.is_null(); }
+ Handle<Map> GetReceiverType() { return receiver_type_; }
bool IsCompileTimeValue();
@@ -1336,6 +1341,7 @@
Expression* value_;
Kind kind_;
bool emit_store_;
+ Handle<Map> receiver_type_;
};
DECLARE_NODE_TYPE(ObjectLiteral)
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc Mon Mar 12 05:49:41 2012
+++ /branches/bleeding_edge/src/hydrogen.cc Tue Mar 13 05:11:46 2012
@@ -3738,18 +3738,13 @@
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));
}
@@ -3950,6 +3945,25 @@
value,
function_strict_mode_flag());
}
+
+
+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,
=======================================
--- /branches/bleeding_edge/src/hydrogen.h Tue Feb 28 02:12:39 2012
+++ /branches/bleeding_edge/src/hydrogen.h Tue Mar 13 05:11:46 2012
@@ -1077,6 +1077,9 @@
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,
=======================================
--- /branches/bleeding_edge/src/type-info.cc Fri Mar 2 03:33:33 2012
+++ /branches/bleeding_edge/src/type-info.cc Tue Mar 13 05:11:46 2012
@@ -152,6 +152,13 @@
Handle<Object> value = GetInfo(expr->id());
return value->IsJSFunction();
}
+
+
+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) {
@@ -266,6 +273,13 @@
Handle<JSFunction> TypeFeedbackOracle::GetCallNewTarget(CallNew* expr) {
return Handle<JSFunction>::cast(GetInfo(expr->id()));
}
+
+
+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) {
=======================================
--- /branches/bleeding_edge/src/type-info.h Fri Mar 2 03:33:33 2012
+++ /branches/bleeding_edge/src/type-info.h Tue Mar 13 05:11:46 2012
@@ -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 @@
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 @@
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