Cleaned up BuildLoadNamed/BuildStoreNamed.

This is a refactoring-only CL and the second one in a series for enabling
inlining of accessors. It makes BuildLoadNamed and BuildStoreNamed a bit more
uniform and makes it clear that they both handle monomorphic accesses only.

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12205 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent bcc175ad
...@@ -4764,12 +4764,18 @@ void HGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { ...@@ -4764,12 +4764,18 @@ void HGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
property->RecordTypeFeedback(oracle()); property->RecordTypeFeedback(oracle());
CHECK_ALIVE(VisitForValue(value)); CHECK_ALIVE(VisitForValue(value));
HValue* value = Pop(); HValue* value = Pop();
Handle<Map> map = property->GetReceiverType();
Handle<String> name = property->key()->AsPropertyName(); Handle<String> name = property->key()->AsPropertyName();
HInstruction* store; HInstruction* store;
CHECK_ALIVE(store = BuildStoreNamed(literal, if (map.is_null()) {
name, // If we don't know the monomorphic type, do a generic store.
value, CHECK_ALIVE(store = BuildStoreNamedGeneric(literal, name, value));
property->GetReceiverType())); } else {
CHECK_ALIVE(store = BuildStoreNamedMonomorphic(literal,
name,
value,
map));
}
AddInstruction(store); AddInstruction(store);
if (store->HasObservableSideEffects()) AddSimulate(key->id()); if (store->HasObservableSideEffects()) AddSimulate(key->id());
} else { } else {
...@@ -5039,13 +5045,10 @@ HInstruction* HGraphBuilder::BuildCallSetter(HValue* object, ...@@ -5039,13 +5045,10 @@ HInstruction* HGraphBuilder::BuildCallSetter(HValue* object,
} }
HInstruction* HGraphBuilder::BuildStoreNamed(HValue* object, HInstruction* HGraphBuilder::BuildStoreNamedMonomorphic(HValue* object,
Handle<String> name, Handle<String> name,
HValue* value, HValue* value,
Handle<Map> map) { Handle<Map> map) {
// If we don't know the monomorphic type, do a generic store.
if (map.is_null()) return BuildStoreNamedGeneric(object, name, value);
// Handle a store to a known field. // Handle a store to a known field.
LookupResult lookup(isolate()); LookupResult lookup(isolate());
if (ComputeLoadStoreField(map, name, &lookup, true)) { if (ComputeLoadStoreField(map, name, &lookup, true)) {
...@@ -5233,11 +5236,8 @@ void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) { ...@@ -5233,11 +5236,8 @@ void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
SmallMapList* types = expr->GetReceiverTypes(); SmallMapList* types = expr->GetReceiverTypes();
if (expr->IsMonomorphic()) { if (expr->IsMonomorphic()) {
CHECK_ALIVE(instr = BuildStoreNamed(object, Handle<Map> map = types->first();
name, CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object, name, value, map));
value,
types->first()));
} else if (types != NULL && types->length() > 1) { } else if (types != NULL && types->length() > 1) {
HandlePolymorphicStoreNamedField(expr, object, value, types, name); HandlePolymorphicStoreNamedField(expr, object, value, types, name);
return; return;
...@@ -5401,7 +5401,7 @@ void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { ...@@ -5401,7 +5401,7 @@ void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
HInstruction* load; HInstruction* load;
if (prop->IsMonomorphic()) { if (prop->IsMonomorphic()) {
map = prop->GetReceiverTypes()->first(); map = prop->GetReceiverTypes()->first();
load = BuildLoadNamed(object, name, prop, map); load = BuildLoadNamedMonomorphic(object, name, prop, map);
} else { } else {
load = BuildLoadNamedGeneric(object, name, prop); load = BuildLoadNamedGeneric(object, name, prop);
} }
...@@ -5417,7 +5417,15 @@ void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { ...@@ -5417,7 +5417,15 @@ void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
if (instr->HasObservableSideEffects()) AddSimulate(operation->id()); if (instr->HasObservableSideEffects()) AddSimulate(operation->id());
HInstruction* store; HInstruction* store;
CHECK_ALIVE(store = BuildStoreNamed(object, name, instr, map)); if (map.is_null()) {
// If we don't know the monomorphic type, do a generic store.
CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, instr));
} else {
CHECK_ALIVE(store = BuildStoreNamedMonomorphic(object,
name,
instr,
map));
}
AddInstruction(store); AddInstruction(store);
// Drop the simulated receiver and value. Return the value. // Drop the simulated receiver and value. Return the value.
Drop(2); Drop(2);
...@@ -5640,7 +5648,7 @@ HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, ...@@ -5640,7 +5648,7 @@ HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object,
} }
HInstruction* HGraphBuilder::BuildLoadNamedGeneric(HValue* obj, HInstruction* HGraphBuilder::BuildLoadNamedGeneric(HValue* object,
Handle<String> name, Handle<String> name,
Property* expr) { Property* expr) {
if (expr->IsUninitialized() && !FLAG_always_opt) { if (expr->IsUninitialized() && !FLAG_always_opt) {
...@@ -5648,7 +5656,7 @@ HInstruction* HGraphBuilder::BuildLoadNamedGeneric(HValue* obj, ...@@ -5648,7 +5656,7 @@ HInstruction* HGraphBuilder::BuildLoadNamedGeneric(HValue* obj,
current_block()->MarkAsDeoptimizing(); current_block()->MarkAsDeoptimizing();
} }
HValue* context = environment()->LookupContext(); HValue* context = environment()->LookupContext();
return new(zone()) HLoadNamedGeneric(context, obj, name); return new(zone()) HLoadNamedGeneric(context, object, name);
} }
...@@ -5663,20 +5671,27 @@ HInstruction* HGraphBuilder::BuildCallGetter(HValue* object, ...@@ -5663,20 +5671,27 @@ HInstruction* HGraphBuilder::BuildCallGetter(HValue* object,
} }
HInstruction* HGraphBuilder::BuildLoadNamed(HValue* object, HInstruction* HGraphBuilder::BuildLoadNamedMonomorphic(HValue* object,
Handle<String> name, Handle<String> name,
Property* expr, Property* expr,
Handle<Map> map) { Handle<Map> map) {
// Handle a load from a known field.
LookupResult lookup(isolate()); LookupResult lookup(isolate());
map->LookupDescriptor(NULL, *name, &lookup); map->LookupDescriptor(NULL, *name, &lookup);
if (lookup.IsField()) { if (lookup.IsField()) {
return BuildLoadNamedField(object, map, &lookup, true); return BuildLoadNamedField(object, map, &lookup, true);
} else if (lookup.IsConstantFunction()) { }
// Handle a load of a constant known function.
if (lookup.IsConstantFunction()) {
AddInstruction(new(zone()) HCheckNonSmi(object)); AddInstruction(new(zone()) HCheckNonSmi(object));
AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone())); AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone()));
Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map));
return new(zone()) HConstant(function, Representation::Tagged()); return new(zone()) HConstant(function, Representation::Tagged());
} else if (lookup.IsPropertyCallbacks()) { }
// Handle a known getter directly in the receiver.
if (lookup.IsPropertyCallbacks()) {
Handle<Object> callback(lookup.GetValueFromMap(*map)); Handle<Object> callback(lookup.GetValueFromMap(*map));
Handle<JSObject> holder; Handle<JSObject> holder;
if (!callback->IsAccessorPair()) { if (!callback->IsAccessorPair()) {
...@@ -5684,19 +5699,22 @@ HInstruction* HGraphBuilder::BuildLoadNamed(HValue* object, ...@@ -5684,19 +5699,22 @@ HInstruction* HGraphBuilder::BuildLoadNamed(HValue* object,
} }
Handle<AccessorPair> accessors = Handle<AccessorPair>::cast(callback); Handle<AccessorPair> accessors = Handle<AccessorPair>::cast(callback);
return BuildCallGetter(object, map, accessors, holder); return BuildCallGetter(object, map, accessors, holder);
} else { }
LookupInPrototypes(map, name, &lookup);
if (lookup.IsPropertyCallbacks()) { // Handle a known getter somewhere in the prototype chain.
Handle<Object> callback(lookup.GetValue()); LookupInPrototypes(map, name, &lookup);
if (lookup.IsPropertyCallbacks()) {
Handle<Object> callback(lookup.GetValue());
Handle<JSObject> holder(lookup.holder()); Handle<JSObject> holder(lookup.holder());
if (!callback->IsAccessorPair()) { if (!callback->IsAccessorPair()) {
return BuildLoadNamedGeneric(object, name, expr); return BuildLoadNamedGeneric(object, name, expr);
} }
Handle<AccessorPair> accessors = Handle<AccessorPair>::cast(callback); Handle<AccessorPair> accessors = Handle<AccessorPair>::cast(callback);
return BuildCallGetter(object, map, accessors, holder); return BuildCallGetter(object, map, accessors, holder);
}
return BuildLoadNamedGeneric(object, name, expr);
} }
// No luck, do a generic load.
return BuildLoadNamedGeneric(object, name, expr);
} }
...@@ -6315,7 +6333,7 @@ void HGraphBuilder::VisitProperty(Property* expr) { ...@@ -6315,7 +6333,7 @@ void HGraphBuilder::VisitProperty(Property* expr) {
HValue* obj = Pop(); HValue* obj = Pop();
if (expr->IsMonomorphic()) { if (expr->IsMonomorphic()) {
instr = BuildLoadNamed(obj, name, expr, types->first()); instr = BuildLoadNamedMonomorphic(obj, name, expr, types->first());
} else if (types != NULL && types->length() > 1) { } else if (types != NULL && types->length() > 1) {
AddInstruction(new(zone()) HCheckNonSmi(obj)); AddInstruction(new(zone()) HCheckNonSmi(obj));
HandlePolymorphicLoadNamedField(expr, obj, types, name); HandlePolymorphicLoadNamedField(expr, obj, types, name);
...@@ -7798,16 +7816,16 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) { ...@@ -7798,16 +7816,16 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) {
if (returns_original_input) Push(graph_->GetConstantUndefined()); if (returns_original_input) Push(graph_->GetConstantUndefined());
CHECK_ALIVE(VisitForValue(prop->obj())); CHECK_ALIVE(VisitForValue(prop->obj()));
HValue* obj = Top(); HValue* object = Top();
Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
Handle<Map> map; Handle<Map> map;
HInstruction* load; HInstruction* load;
if (prop->IsMonomorphic()) { if (prop->IsMonomorphic()) {
map = prop->GetReceiverTypes()->first(); map = prop->GetReceiverTypes()->first();
load = BuildLoadNamed(obj, name, prop, map); load = BuildLoadNamedMonomorphic(object, name, prop, map);
} else { } else {
load = BuildLoadNamedGeneric(obj, name, prop); load = BuildLoadNamedGeneric(object, name, prop);
} }
PushAndAdd(load); PushAndAdd(load);
if (load->HasObservableSideEffects()) AddSimulate(expr->CountId()); if (load->HasObservableSideEffects()) AddSimulate(expr->CountId());
...@@ -7816,7 +7834,15 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) { ...@@ -7816,7 +7834,15 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) {
input = Pop(); input = Pop();
HInstruction* store; HInstruction* store;
CHECK_ALIVE(store = BuildStoreNamed(obj, name, after, map)); if (map.is_null()) {
// If we don't know the monomorphic type, do a generic store.
CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, after));
} else {
CHECK_ALIVE(store = BuildStoreNamedMonomorphic(object,
name,
after,
map));
}
AddInstruction(store); AddInstruction(store);
// Overwrite the receiver in the bailout environment with the result // Overwrite the receiver in the bailout environment with the result
......
...@@ -1151,19 +1151,19 @@ class HGraphBuilder: public AstVisitor { ...@@ -1151,19 +1151,19 @@ class HGraphBuilder: public AstVisitor {
Handle<Map> map, Handle<Map> map,
Handle<AccessorPair> accessors, Handle<AccessorPair> accessors,
Handle<JSObject> holder); Handle<JSObject> holder);
HInstruction* BuildLoadNamed(HValue* object, HInstruction* BuildLoadNamedMonomorphic(HValue* object,
Handle<String> name, Handle<String> name,
Property* expr, Property* expr,
Handle<Map> map); Handle<Map> map);
HInstruction* BuildCallSetter(HValue* object, HInstruction* BuildCallSetter(HValue* object,
HValue* value, HValue* value,
Handle<Map> map, Handle<Map> map,
Handle<AccessorPair> accessors, Handle<AccessorPair> accessors,
Handle<JSObject> holder); Handle<JSObject> holder);
HInstruction* BuildStoreNamed(HValue* object, HInstruction* BuildStoreNamedMonomorphic(HValue* object,
Handle<String> name, Handle<String> name,
HValue* value, HValue* value,
Handle<Map> map); Handle<Map> map);
HInstruction* BuildStoreNamedField(HValue* object, HInstruction* BuildStoreNamedField(HValue* object,
Handle<String> name, Handle<String> name,
HValue* value, HValue* value,
......
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