Chromium Code Reviews| Index: src/ia32/lithium-codegen-ia32.cc |
| diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc |
| index 05152b7ce8efe6b5a1fc4279241501cd0a72aad8..8bb3dd2ec7ff5048e288fc8805bd9562254d9ee7 100644 |
| --- a/src/ia32/lithium-codegen-ia32.cc |
| +++ b/src/ia32/lithium-codegen-ia32.cc |
| @@ -5505,6 +5505,10 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { |
| DeoptimizeIf(not_equal, instr->environment()); |
| } |
| + int flags = allocation_site_mode == TRACK_ALLOCATION_SITE |
| + ? ArrayLiteral::kAllocationSiteInfoAllowed |
| + : ArrayLiteral::kNoFlags; |
| + |
| // Set up the parameters to the stub/runtime call. |
| __ PushHeapObject(literals); |
| __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index()))); |
| @@ -5521,9 +5525,11 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { |
| FastCloneShallowArrayStub stub(mode, DONT_TRACK_ALLOCATION_SITE, length); |
| CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
| } else if (instr->hydrogen()->depth() > 1) { |
| - CallRuntime(Runtime::kCreateArrayLiteral, 3, instr); |
| + __ push(Immediate(Smi::FromInt(flags))); |
| + CallRuntime(Runtime::kCreateArrayLiteral, 4, instr); |
| } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) { |
| - CallRuntime(Runtime::kCreateArrayLiteralShallow, 3, instr); |
| + __ push(Immediate(Smi::FromInt(flags))); |
| + CallRuntime(Runtime::kCreateArrayLiteralShallow, 4, instr); |
| } else { |
| FastCloneShallowArrayStub::Mode mode = |
| boilerplate_elements_kind == FAST_DOUBLE_ELEMENTS |
| @@ -5536,6 +5542,7 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { |
| void LCodeGen::EmitDeepCopy(Handle<JSObject> object, |
| + Handle<JSObject> original_object, |
| Register result, |
| Register source, |
| int* offset, |
| @@ -5543,8 +5550,9 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object, |
| ASSERT(!source.is(ecx)); |
| ASSERT(!result.is(ecx)); |
| + // Should we track allocation info for *this* object in the tree? |
| bool create_allocation_site_info = mode == TRACK_ALLOCATION_SITE && |
| - object->map()->CanTrackAllocationSite(); |
| + object->IsJSArray() && object->ShouldTrackAllocationInfo(); |
| if (FLAG_debug_code) { |
| __ LoadHeapObject(ecx, object); |
| @@ -5561,6 +5569,7 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object, |
| // Only elements backing stores for non-COW arrays need to be copied. |
| Handle<FixedArrayBase> elements(object->elements()); |
| + Handle<FixedArrayBase> original_elements(original_object->elements()); |
| bool has_elements = elements->length() > 0 && |
| elements->map() != isolate()->heap()->fixed_cow_array_map(); |
| @@ -5596,11 +5605,14 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object, |
| Handle<Object> value = Handle<Object>(object->InObjectPropertyAt(i)); |
| if (value->IsJSObject()) { |
| Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
| + Handle<JSObject> original_value_object = Handle<JSObject>::cast( |
| + Handle<Object>(original_object->InObjectPropertyAt(i))); |
| + |
| __ lea(ecx, Operand(result, *offset)); |
| __ mov(FieldOperand(result, total_offset), ecx); |
| __ LoadHeapObject(source, value_object); |
| - EmitDeepCopy(value_object, result, source, offset, |
| - DONT_TRACK_ALLOCATION_SITE); |
| + EmitDeepCopy(value_object, original_value_object, result, source, |
| + offset, mode); |
| } else if (value->IsHeapObject()) { |
| __ LoadHeapObject(ecx, Handle<HeapObject>::cast(value)); |
| __ mov(FieldOperand(result, total_offset), ecx); |
| @@ -5611,10 +5623,12 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object, |
| // Build Allocation Site Info if desired |
| if (create_allocation_site_info) { |
| - __ mov(FieldOperand(result, object_size), |
| + __ mov(FieldOperand(result, object_size + object_offset), |
| Immediate(Handle<Map>(isolate()->heap()-> |
| allocation_site_info_map()))); |
| - __ mov(FieldOperand(result, object_size + kPointerSize), source); |
| + __ LoadHeapObject(ecx, original_object); |
| + __ mov(FieldOperand(result, object_size + object_offset + kPointerSize), |
| + ecx); |
| } |
| if (has_elements) { |
| @@ -5641,16 +5655,22 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object, |
| } |
| } else if (elements->IsFixedArray()) { |
| Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); |
| + ASSERT(original_object->HasFastObjectElements()); |
| + Handle<FixedArray> original_fast_elements = |
| + Handle<FixedArray>::cast(original_elements); |
| for (int i = 0; i < elements_length; i++) { |
| int total_offset = elements_offset + FixedArray::OffsetOfElementAt(i); |
| Handle<Object> value(fast_elements->get(i)); |
| if (value->IsJSObject()) { |
| Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
| + Handle<JSObject> original_value_object = Handle<JSObject>::cast( |
| + Handle<Object>(original_fast_elements->get(i))); |
| __ lea(ecx, Operand(result, *offset)); |
| __ mov(FieldOperand(result, total_offset), ecx); |
| __ LoadHeapObject(source, value_object); |
| - EmitDeepCopy(value_object, result, source, offset, |
| - DONT_TRACK_ALLOCATION_SITE); |
| + ASSERT(!value_object.is_identical_to(original_value_object)); |
| + EmitDeepCopy(value_object, original_value_object, result, source, |
| + offset, mode); |
| } else if (value->IsHeapObject()) { |
| __ LoadHeapObject(ecx, Handle<HeapObject>::cast(value)); |
| __ mov(FieldOperand(result, total_offset), ecx); |
| @@ -5668,24 +5688,6 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object, |
| void LCodeGen::DoFastLiteral(LFastLiteral* instr) { |
| ASSERT(ToRegister(instr->context()).is(esi)); |
| int size = instr->hydrogen()->total_size(); |
| - ElementsKind boilerplate_elements_kind = |
| - instr->hydrogen()->boilerplate()->GetElementsKind(); |
| - |
| - // Deopt if the literal boilerplate ElementsKind is of a type different than |
| - // the expected one. The check isn't necessary if the boilerplate has already |
| - // already been converted to TERMINAL_FAST_ELEMENTS_KIND. |
| - if (CanTransitionToMoreGeneralFastElementsKind( |
| - boilerplate_elements_kind, true)) { |
| - __ LoadHeapObject(ebx, instr->hydrogen()->boilerplate()); |
| - __ mov(ecx, FieldOperand(ebx, HeapObject::kMapOffset)); |
| - // Load the map's "bit field 2". We only need the first byte, |
| - // but the following masking takes care of that anyway. |
| - __ mov(ecx, FieldOperand(ecx, Map::kBitField2Offset)); |
| - // Retrieve elements_kind from bit field 2. |
| - __ and_(ecx, Map::kElementsKindMask); |
| - __ cmp(ecx, boilerplate_elements_kind << Map::kElementsKindShift); |
| - DeoptimizeIf(not_equal, instr->environment()); |
| - } |
| // Allocate all objects that are part of the literal in one big |
| // allocation. This avoids multiple limit checks. |
| @@ -5700,7 +5702,9 @@ void LCodeGen::DoFastLiteral(LFastLiteral* instr) { |
| __ bind(&allocated); |
| int offset = 0; |
| __ LoadHeapObject(ebx, instr->hydrogen()->boilerplate()); |
| - EmitDeepCopy(instr->hydrogen()->boilerplate(), eax, ebx, &offset, |
| + EmitDeepCopy(instr->hydrogen()->boilerplate(), |
| + instr->hydrogen()->original_boilerplate(), |
| + eax, ebx, &offset, |
| instr->hydrogen()->allocation_site_mode()); |
| ASSERT_EQ(size, offset); |
| } |
| @@ -5722,6 +5726,11 @@ void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { |
| flags |= instr->hydrogen()->has_function() |
| ? ObjectLiteral::kHasFunction |
| : ObjectLiteral::kNoFlags; |
| + |
| + if (instr->hydrogen()->allocation_site_mode() == TRACK_ALLOCATION_SITE) { |
|
danno
2013/02/11 15:05:21
If you check for FLAG_track_allocation_sites in th
|
| + flags |= ObjectLiteral::kAllocationSiteInfoAllowed; |
| + } |
| + |
| __ push(Immediate(Smi::FromInt(flags))); |
| // Pick the right runtime function or stub to call. |