| Index: src/hydrogen.cc
|
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc
|
| index a6b60b1f77a8fc439409096fbd88cd6c7b79006c..29aff88395d68cbd437e03b081de29702722a9d7 100644
|
| --- a/src/hydrogen.cc
|
| +++ b/src/hydrogen.cc
|
| @@ -3437,19 +3437,35 @@ 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
|
| +// Determines whether the given array or 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;
|
| +static bool IsFastLiteral(Handle<JSObject> boilerplate,
|
| + int max_depth,
|
| + int* max_properties,
|
| + int* total_size) {
|
| + ASSERT(max_depth >= 0 && *max_properties >= 0);
|
| + if (max_depth == 0) return false;
|
|
|
| Handle<FixedArrayBase> elements(boilerplate->elements());
|
| if (elements->length() > 0 &&
|
| - elements->map() != HEAP->fixed_cow_array_map()) {
|
| - return false;
|
| + elements->map() != boilerplate->GetHeap()->fixed_cow_array_map()) {
|
| + if (!boilerplate->HasFastElements()) return false;
|
| + int length = elements->length();
|
| + for (int i = 0; i < length; i++) {
|
| + if ((*max_properties)-- == 0) return false;
|
| + Handle<Object> value = JSObject::GetElement(boilerplate, i);
|
| + if (value->IsJSObject()) {
|
| + Handle<JSObject> value_object = Handle<JSObject>::cast(value);
|
| + if (!IsFastLiteral(value_object,
|
| + max_depth - 1,
|
| + max_properties,
|
| + total_size)) {
|
| + return false;
|
| + }
|
| + }
|
| + }
|
| + *total_size += FixedArray::SizeFor(length);
|
| }
|
|
|
| Handle<FixedArray> properties(boilerplate->properties());
|
| @@ -3458,14 +3474,14 @@ static bool IsFastObjectLiteral(Handle<JSObject> boilerplate,
|
| } else {
|
| int nof = boilerplate->map()->inobject_properties();
|
| for (int i = 0; i < nof; i++) {
|
| - if ((*max_properties)-- <= 0) return false;
|
| + 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)) {
|
| + if (!IsFastLiteral(value_object,
|
| + max_depth - 1,
|
| + max_properties,
|
| + total_size)) {
|
| return false;
|
| }
|
| }
|
| @@ -3487,26 +3503,26 @@ void HGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
|
|
|
| // Check whether to use fast or slow deep-copying for boilerplate.
|
| int total_size = 0;
|
| - int max_properties = HObjectLiteralFast::kMaxObjectLiteralProperties;
|
| + int max_properties = HFastLiteral::kMaxLiteralProperties;
|
| Handle<Object> boilerplate(closure->literals()->get(expr->literal_index()));
|
| if (boilerplate->IsJSObject() &&
|
| - IsFastObjectLiteral(Handle<JSObject>::cast(boilerplate),
|
| - HObjectLiteralFast::kMaxObjectLiteralDepth,
|
| - &max_properties,
|
| - &total_size)) {
|
| + IsFastLiteral(Handle<JSObject>::cast(boilerplate),
|
| + HFastLiteral::kMaxLiteralDepth,
|
| + &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());
|
| + literal = new(zone()) HFastLiteral(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());
|
| + literal = new(zone()) HObjectLiteral(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
|
| @@ -3577,6 +3593,7 @@ void HGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
|
| ZoneList<Expression*>* subexprs = expr->values();
|
| int length = subexprs->length();
|
| HValue* context = environment()->LookupContext();
|
| + HInstruction* literal;
|
|
|
| Handle<FixedArray> literals(environment()->closure()->literals());
|
| Handle<Object> raw_boilerplate(literals->get(expr->literal_index()));
|
| @@ -3598,12 +3615,25 @@ void HGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
|
| ElementsKind boilerplate_elements_kind =
|
| Handle<JSObject>::cast(boilerplate)->GetElementsKind();
|
|
|
| - HArrayLiteral* literal = new(zone()) HArrayLiteral(
|
| - context,
|
| - boilerplate,
|
| - length,
|
| - expr->literal_index(),
|
| - expr->depth());
|
| + // Check whether to use fast or slow deep-copying for boilerplate.
|
| + int total_size = 0;
|
| + int max_properties = HFastLiteral::kMaxLiteralProperties;
|
| + if (IsFastLiteral(boilerplate,
|
| + HFastLiteral::kMaxLiteralDepth,
|
| + &max_properties,
|
| + &total_size)) {
|
| + literal = new(zone()) HFastLiteral(context,
|
| + boilerplate,
|
| + total_size,
|
| + expr->literal_index(),
|
| + expr->depth());
|
| + } else {
|
| + literal = new(zone()) HArrayLiteral(context,
|
| + boilerplate,
|
| + length,
|
| + expr->literal_index(),
|
| + expr->depth());
|
| + }
|
|
|
| // The array is expected in the bailout environment during computation
|
| // of the property values and is the value of the entire expression.
|
|
|