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.

R=svenpanne@chromium.org

Review URL: https://chromiumcodereview.appspot.com/9692036

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11023 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 7d6fd56f
......@@ -602,6 +602,13 @@ void CompareOperation::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
}
void ObjectLiteral::Property::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
receiver_type_ = oracle->ObjectLiteralStoreIsMonomorphic(this)
? oracle->GetObjectLiteralStoreMap(this)
: Handle<Map>::null();
}
// ----------------------------------------------------------------------------
// Implementation of AstVisitor
......
......@@ -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 !receiver_type_.is_null(); }
Handle<Map> GetReceiverType() { return receiver_type_; }
bool IsCompileTimeValue();
void set_emit_store(bool emit_store);
......@@ -1336,6 +1341,7 @@ class ObjectLiteral: public MaterializedLiteral {
Expression* value_;
Kind kind_;
bool emit_store_;
Handle<Map> receiver_type_;
};
DECLARE_NODE_TYPE(ObjectLiteral)
......
......@@ -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));
}
......@@ -3952,6 +3947,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) {
......
......@@ -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,
......
......@@ -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);
......
......@@ -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
......
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