Revision: 15158
Author: [email protected]
Date: Fri Jun 14 07:16:03 2013
Log: Try convert polymorphic stores into a single monomorphic store.
[email protected]
Review URL: https://chromiumcodereview.appspot.com/16975006
http://code.google.com/p/v8/source/detail?r=15158
Modified:
/branches/bleeding_edge/src/hydrogen.cc
/branches/bleeding_edge/src/hydrogen.h
/branches/bleeding_edge/src/property-details.h
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc Fri Jun 14 00:45:16 2013
+++ /branches/bleeding_edge/src/hydrogen.cc Fri Jun 14 07:16:03 2013
@@ -3794,6 +3794,13 @@
} while (false)
+#define CHECK_ALIVE_OR_RETURN(call, value) \
+ do { \
+ call; \
+ if (HasStackOverflow() || current_block() == NULL) return value; \
+ } while (false)
+
+
void HOptimizedGraphBuilder::Bailout(const char* reason) {
current_info()->set_bailout_reason(reason);
SetStackOverflow();
@@ -6300,13 +6307,13 @@
Handle<String> name) {
// Use monomorphic load if property lookup results in the same field
index
// for all maps. Requires special map check on the set of all handled
maps.
+ if (types->length() > kMaxLoadPolymorphism) return NULL;
+
LookupResult lookup(isolate());
int count;
Representation representation = Representation::None();
HObjectAccess access = HObjectAccess::ForMap(); // initial value unused.
- for (count = 0;
- count < types->length() && count < kMaxLoadPolymorphism;
- ++count) {
+ for (count = 0; count < types->length(); ++count) {
Handle<Map> map = types->at(count);
if (!ComputeLoadStoreField(map, name, &lookup, false)) break;
@@ -6317,7 +6324,6 @@
if (count == 0) {
// First time through the loop; set access and representation.
access = new_access;
- representation = new_representation;
} else if (!representation.IsCompatibleForLoad(new_representation)) {
// Representations did not match.
break;
@@ -6328,6 +6334,7 @@
// In-objectness did not match.
break;
}
+ representation = representation.generalize(new_representation);
}
if (count != types->length()) return NULL;
@@ -6357,6 +6364,65 @@
instr->set_position(expr->position());
return ast_context()->ReturnInstruction(instr, expr->id());
}
+
+
+bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic(
+ Assignment* expr,
+ HValue* object,
+ HValue* value,
+ SmallMapList* types,
+ Handle<String> name) {
+ // Use monomorphic store if property lookup results in the same field
index
+ // for all maps. Requires special map check on the set of all handled
maps.
+ if (types->length() > kMaxStorePolymorphism) return false;
+
+ // TODO(verwaest): Merge the checking logic with the code in
+ // TryLoadPolymorphicAsMonomorphic.
+ LookupResult lookup(isolate());
+ int count;
+ Representation representation = Representation::None();
+ HObjectAccess access = HObjectAccess::ForMap(); // initial value unused.
+ for (count = 0; count < types->length(); ++count) {
+ Handle<Map> map = types->at(count);
+ // Pass false to ignore transitions.
+ if (!ComputeLoadStoreField(map, name, &lookup, false)) break;
+
+ HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name);
+ Representation new_representation =
+ ComputeLoadStoreRepresentation(map, &lookup);
+
+ if (count == 0) {
+ // First time through the loop; set access and representation.
+ access = new_access;
+ representation = new_representation;
+ } else if (!representation.IsCompatibleForStore(new_representation)) {
+ // Representations did not match.
+ break;
+ } else if (access.offset() != new_access.offset()) {
+ // Offsets did not match.
+ break;
+ } else if (access.IsInobject() != new_access.IsInobject()) {
+ // In-objectness did not match.
+ break;
+ }
+ }
+
+ if (count != types->length()) return false;
+
+ // Everything matched; can use monomorphic store.
+ BuildCheckNonSmi(object);
+ AddInstruction(HCheckMaps::New(object, types, zone()));
+ HInstruction* store;
+ CHECK_ALIVE_OR_RETURN(
+ store = BuildStoreNamedField(object, name, value, types->at(0),
&lookup),
+ true);
+ Push(value);
+ store->set_position(expr->position());
+ AddInstruction(store);
+ AddSimulate(expr->AssignmentId());
+ ast_context()->ReturnValue(Pop());
+ return true;
+}
void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField(
@@ -6365,6 +6431,10 @@
HValue* value,
SmallMapList* types,
Handle<String> name) {
+ if (TryStorePolymorphicAsMonomorphic(expr, object, value, types, name)) {
+ return;
+ }
+
// TODO(ager): We should recognize when the prototype chains for
different
// maps are identical. In that case we can avoid repeatedly generating
the
// same prototype map checks.
@@ -6387,8 +6457,8 @@
set_current_block(if_true);
HInstruction* instr;
- CHECK_ALIVE(instr =
- BuildStoreNamedField(object, name, value, map, &lookup));
+ CHECK_ALIVE(
+ instr = BuildStoreNamedField(object, name, value, map, &lookup));
instr->set_position(expr->position());
// Goto will add the HSimulate for the store.
AddInstruction(instr);
@@ -6432,7 +6502,7 @@
ASSERT(join != NULL);
join->SetJoinId(expr->id());
set_current_block(join);
- if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop());
+ if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop());
}
=======================================
--- /branches/bleeding_edge/src/hydrogen.h Thu Jun 13 11:09:33 2013
+++ /branches/bleeding_edge/src/hydrogen.h Fri Jun 14 07:16:03 2013
@@ -1705,6 +1705,11 @@
void HandlePolymorphicStoreNamedField(Assignment* expr,
HValue* object,
HValue* value,
+ SmallMapList* types,
+ Handle<String> name);
+ bool TryStorePolymorphicAsMonomorphic(Assignment* expr,
+ HValue* object,
+ HValue* value,
SmallMapList* types,
Handle<String> name);
void HandlePolymorphicCallNamed(Call* expr,
=======================================
--- /branches/bleeding_edge/src/property-details.h Thu Jun 6 07:21:35 2013
+++ /branches/bleeding_edge/src/property-details.h Fri Jun 14 07:16:03 2013
@@ -109,6 +109,10 @@
return (IsDouble() && other.IsDouble()) ||
(!IsDouble() && !other.IsDouble());
}
+
+ bool IsCompatibleForStore(const Representation& other) const {
+ return Equals(other);
+ }
bool is_more_general_than(const Representation& other) const {
ASSERT(kind_ != kExternal);
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.