Index: src/hydrogen.cc |
diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
index 39a68cc6e1e946b1b006c1ef2caa4d5dbcc390a9..fa46bb9bbe0196de91dbff0b531d609172986e95 100644 |
--- a/src/hydrogen.cc |
+++ b/src/hydrogen.cc |
@@ -3316,18 +3316,78 @@ void HGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { |
} |
+// Determines whether the given object literal boilerplate satisfies all |
+// limits to be considered for fast deep-copying and computes the total |
+// size of all objects that are part of the graph. |
+static bool IsFastObjectLiteral(Handle<JSObject> boilerplate, |
+ int max_depth, |
+ int* max_properties, |
+ int* total_size) { |
+ if (max_depth <= 0) return false; |
+ |
+ FixedArrayBase* elements = boilerplate->elements(); |
+ if (elements->length() > 0 && |
+ elements->map() != HEAP->fixed_cow_array_map()) { |
+ return false; |
+ } |
+ |
+ FixedArray* properties = boilerplate->properties(); |
+ if (properties->length() > 0) { |
+ return false; |
+ } else { |
+ int nof = boilerplate->map()->inobject_properties(); |
+ for (int i = 0; i < nof; i++) { |
+ if ((*max_properties)-- <= 0) return false; |
+ Handle<Object> value(boilerplate->InObjectPropertyAt(i)); |
+ if (value->IsJSObject()) { |
+ Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
+ if (!IsFastObjectLiteral(value_object, |
+ max_depth - 1, |
+ max_properties, |
+ total_size)) { |
+ return false; |
+ } |
+ } |
+ } |
+ } |
+ |
+ *total_size += boilerplate->map()->instance_size(); |
+ return true; |
+} |
+ |
+ |
void HGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { |
ASSERT(!HasStackOverflow()); |
ASSERT(current_block() != NULL); |
ASSERT(current_block()->HasPredecessor()); |
+ Handle<JSFunction> closure = function_state()->compilation_info()->closure(); |
HValue* context = environment()->LookupContext(); |
- HObjectLiteral* literal = |
- new(zone()) HObjectLiteral(context, |
- expr->constant_properties(), |
- expr->fast_elements(), |
- expr->literal_index(), |
- expr->depth(), |
- expr->has_function()); |
+ HInstruction* literal; |
+ |
+ // Check whether to use fast or slow deep-copying for boilerplate. |
+ int total_size = 0; |
+ int max_properties = HObjectLiteralFast::kMaxObjectLiteralProperties; |
+ Handle<Object> boilerplate(closure->literals()->get(expr->literal_index())); |
+ if (boilerplate->IsJSObject() && |
+ IsFastObjectLiteral(Handle<JSObject>::cast(boilerplate), |
+ HObjectLiteralFast::kMaxObjectLiteralDepth, |
+ &max_properties, |
+ &total_size)) { |
+ Handle<JSObject> boilerplate_object = Handle<JSObject>::cast(boilerplate); |
+ literal = new(zone()) HObjectLiteralFast(context, |
+ boilerplate_object, |
+ total_size, |
+ expr->literal_index(), |
+ expr->depth()); |
+ } else { |
+ literal = new(zone()) HObjectLiteralGeneric(context, |
+ expr->constant_properties(), |
+ expr->fast_elements(), |
+ expr->literal_index(), |
+ expr->depth(), |
+ expr->has_function()); |
+ } |
+ |
// The object is expected in the bailout environment during computation |
// of the property values and is the value of the entire expression. |
PushAndAdd(literal); |