Chromium Code Reviews| Index: src/arm/lithium-codegen-arm.cc |
| diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc |
| index 45ebfae2c4d53278cfd0d2e12a491ded77d475c6..cc3f6099291d68edcee4ceaf6db86209470bf756 100644 |
| --- a/src/arm/lithium-codegen-arm.cc |
| +++ b/src/arm/lithium-codegen-arm.cc |
| @@ -840,18 +840,18 @@ void LCodeGen::DeoptimizeIf(Condition cc, LEnvironment* environment) { |
| if (FLAG_trap_on_deopt) __ stop("trap_on_deopt", cc); |
| - bool needs_lazy_deopt = info()->IsStub(); |
| + bool lazy_deopt_needed = info()->IsStub(); |
|
danno
2013/02/11 15:05:21
This change and the changes in the following lines
mvstanton
2013/02/15 07:36:43
Done.
|
| ASSERT(info()->IsStub() || frame_is_built_); |
| - if (cc == al && !needs_lazy_deopt) { |
| + if (cc == al && !lazy_deopt_needed && frame_is_built_) { |
| __ Jump(entry, RelocInfo::RUNTIME_ENTRY); |
| } else { |
| // We often have several deopts to the same entry, reuse the last |
| // jump entry if this is the case. |
| if (deopt_jump_table_.is_empty() || |
| (deopt_jump_table_.last().address != entry) || |
| - (deopt_jump_table_.last().is_lazy_deopt != needs_lazy_deopt) || |
| + (deopt_jump_table_.last().is_lazy_deopt != lazy_deopt_needed) || |
| (deopt_jump_table_.last().needs_frame != !frame_is_built_)) { |
| - JumpTableEntry table_entry(entry, !frame_is_built_, needs_lazy_deopt); |
| + JumpTableEntry table_entry(entry, !frame_is_built_, lazy_deopt_needed); |
| deopt_jump_table_.Add(table_entry, zone()); |
| } |
| __ b(cc, &deopt_jump_table_.last().label); |
| @@ -5638,6 +5638,10 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { |
| DeoptimizeIf(ne, instr->environment()); |
| } |
| + int flags = allocation_site_mode == TRACK_ALLOCATION_SITE |
| + ? ArrayLiteral::kAllocationSiteInfoAllowed |
| + : ArrayLiteral::kNoFlags; |
| + |
| // Set up the parameters to the stub/runtime call. |
| __ LoadHeapObject(r3, literals); |
| __ mov(r2, Operand(Smi::FromInt(instr->hydrogen()->literal_index()))); |
| @@ -5655,9 +5659,13 @@ 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); |
| + __ mov(r0, Operand(Smi::FromInt(flags))); |
| + __ push(r0); |
| + CallRuntime(Runtime::kCreateArrayLiteral, 4, instr); |
| } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) { |
| - CallRuntime(Runtime::kCreateArrayLiteralShallow, 3, instr); |
| + __ mov(r0, Operand(Smi::FromInt(flags))); |
| + __ push(r0); |
| + CallRuntime(Runtime::kCreateArrayLiteralShallow, 4, instr); |
| } else { |
| FastCloneShallowArrayStub::Mode mode = |
| boilerplate_elements_kind == FAST_DOUBLE_ELEMENTS |
| @@ -5670,6 +5678,7 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { |
| void LCodeGen::EmitDeepCopy(Handle<JSObject> object, |
| + Handle<JSObject> original_object, |
| Register result, |
| Register source, |
| int* offset, |
| @@ -5677,11 +5686,13 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object, |
| ASSERT(!source.is(r2)); |
| ASSERT(!result.is(r2)); |
| + // 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(); |
| // 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(); |
| @@ -5717,11 +5728,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))); |
| + |
| __ add(r2, result, Operand(*offset)); |
| __ str(r2, FieldMemOperand(result, total_offset)); |
| __ 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(r2, Handle<HeapObject>::cast(value)); |
| __ str(r2, FieldMemOperand(result, total_offset)); |
| @@ -5735,8 +5749,10 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object, |
| if (create_allocation_site_info) { |
| __ mov(r2, Operand(Handle<Map>(isolate()->heap()-> |
| allocation_site_info_map()))); |
| - __ str(r2, FieldMemOperand(result, object_size)); |
| - __ str(source, FieldMemOperand(result, object_size + kPointerSize)); |
| + __ str(r2, FieldMemOperand(result, object_size + object_offset)); |
| + __ LoadHeapObject(r2, original_object); |
| + __ str(r2, FieldMemOperand(result, |
| + object_size + object_offset + kPointerSize)); |
| } |
| if (has_elements) { |
| @@ -5766,16 +5782,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))); |
| __ add(r2, result, Operand(*offset)); |
| __ str(r2, FieldMemOperand(result, total_offset)); |
| __ 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(r2, Handle<HeapObject>::cast(value)); |
| __ str(r2, FieldMemOperand(result, total_offset)); |
| @@ -5793,26 +5815,7 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object, |
| void LCodeGen::DoFastLiteral(LFastLiteral* instr) { |
| int size = instr->hydrogen()->total_size(); |
| - ElementsKind boilerplate_elements_kind = |
| - instr->hydrogen()->boilerplate()->GetElementsKind(); |
| - // Deopt if the array literal boilerplate ElementsKind is of a type different |
| - // than the expected one. The check isn't necessary if the boilerplate has |
| - // already been converted to TERMINAL_FAST_ELEMENTS_KIND. |
| - if (CanTransitionToMoreGeneralFastElementsKind( |
| - boilerplate_elements_kind, true)) { |
| - __ LoadHeapObject(r1, instr->hydrogen()->boilerplate()); |
| - // Load map into r2. |
| - __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); |
| - // Load the map's "bit field 2". |
| - __ ldrb(r2, FieldMemOperand(r2, Map::kBitField2Offset)); |
| - // Retrieve elements_kind from bit field 2. |
| - __ ubfx(r2, r2, Map::kElementsKindShift, Map::kElementsKindBitCount); |
| - __ cmp(r2, Operand(boilerplate_elements_kind)); |
| - DeoptimizeIf(ne, instr->environment()); |
| - } |
| - |
| - // Allocate all objects that are part of the literal in one big |
| // allocation. This avoids multiple limit checks. |
| Label allocated, runtime_allocate; |
| __ AllocateInNewSpace(size, r0, r2, r3, &runtime_allocate, TAG_OBJECT); |
| @@ -5826,7 +5829,9 @@ void LCodeGen::DoFastLiteral(LFastLiteral* instr) { |
| __ bind(&allocated); |
| int offset = 0; |
| __ LoadHeapObject(r1, instr->hydrogen()->boilerplate()); |
| - EmitDeepCopy(instr->hydrogen()->boilerplate(), r0, r1, &offset, |
| + EmitDeepCopy(instr->hydrogen()->boilerplate(), |
| + instr->hydrogen()->original_boilerplate(), |
| + r0, r1, &offset, |
| instr->hydrogen()->allocation_site_mode()); |
| ASSERT_EQ(size, offset); |
| } |
| @@ -5844,6 +5849,11 @@ void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { |
| int flags = instr->hydrogen()->fast_elements() |
| ? ObjectLiteral::kFastElements |
| : ObjectLiteral::kNoFlags; |
| + |
| + if (instr->hydrogen()->allocation_site_mode() == TRACK_ALLOCATION_SITE) { |
| + flags |= ObjectLiteral::kAllocationSiteInfoAllowed; |
| + } |
| + |
| __ mov(r1, Operand(Smi::FromInt(flags))); |
| __ Push(r4, r3, r2, r1); |