| OLD | NEW | 
|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. | 
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without | 
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are | 
| 4 // met: | 4 // met: | 
| 5 // | 5 // | 
| 6 //     * Redistributions of source code must retain the above copyright | 6 //     * Redistributions of source code must retain the above copyright | 
| 7 //       notice, this list of conditions and the following disclaimer. | 7 //       notice, this list of conditions and the following disclaimer. | 
| 8 //     * Redistributions in binary form must reproduce the above | 8 //     * Redistributions in binary form must reproduce the above | 
| 9 //       copyright notice, this list of conditions and the following | 9 //       copyright notice, this list of conditions and the following | 
| 10 //       disclaimer in the documentation and/or other materials provided | 10 //       disclaimer in the documentation and/or other materials provided | 
| (...skipping 5100 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 5111   __ push(a0); | 5111   __ push(a0); | 
| 5112   CallRuntimeFromDeferred(Runtime::kAllocateInNewSpace, 1, instr); | 5112   CallRuntimeFromDeferred(Runtime::kAllocateInNewSpace, 1, instr); | 
| 5113   __ StoreToSafepointRegisterSlot(v0, result); | 5113   __ StoreToSafepointRegisterSlot(v0, result); | 
| 5114 } | 5114 } | 
| 5115 | 5115 | 
| 5116 | 5116 | 
| 5117 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { | 5117 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { | 
| 5118   Handle<FixedArray> literals(instr->environment()->closure()->literals()); | 5118   Handle<FixedArray> literals(instr->environment()->closure()->literals()); | 
| 5119   ElementsKind boilerplate_elements_kind = | 5119   ElementsKind boilerplate_elements_kind = | 
| 5120       instr->hydrogen()->boilerplate_elements_kind(); | 5120       instr->hydrogen()->boilerplate_elements_kind(); | 
|  | 5121   AllocationSiteMode allocation_site_mode = | 
|  | 5122       instr->hydrogen()->allocation_site_mode(); | 
| 5121 | 5123 | 
| 5122   // Deopt if the array literal boilerplate ElementsKind is of a type different | 5124   // Deopt if the array literal boilerplate ElementsKind is of a type different | 
| 5123   // than the expected one. The check isn't necessary if the boilerplate has | 5125   // than the expected one. The check isn't necessary if the boilerplate has | 
| 5124   // already been converted to TERMINAL_FAST_ELEMENTS_KIND. | 5126   // already been converted to TERMINAL_FAST_ELEMENTS_KIND. | 
| 5125   if (CanTransitionToMoreGeneralFastElementsKind( | 5127   if (CanTransitionToMoreGeneralFastElementsKind( | 
| 5126           boilerplate_elements_kind, true)) { | 5128           boilerplate_elements_kind, true)) { | 
| 5127     __ LoadHeapObject(a1, instr->hydrogen()->boilerplate_object()); | 5129     __ LoadHeapObject(a1, instr->hydrogen()->boilerplate_object()); | 
| 5128     // Load map into a2. | 5130     // Load map into a2. | 
| 5129     __ lw(a2, FieldMemOperand(a1, HeapObject::kMapOffset)); | 5131     __ lw(a2, FieldMemOperand(a1, HeapObject::kMapOffset)); | 
| 5130     // Load the map's "bit field 2". | 5132     // Load the map's "bit field 2". | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
| 5144   // Pass an empty fixed array. | 5146   // Pass an empty fixed array. | 
| 5145   __ li(a1, Operand(isolate()->factory()->empty_fixed_array())); | 5147   __ li(a1, Operand(isolate()->factory()->empty_fixed_array())); | 
| 5146   __ Push(a3, a2, a1); | 5148   __ Push(a3, a2, a1); | 
| 5147 | 5149 | 
| 5148   // Pick the right runtime function or stub to call. | 5150   // Pick the right runtime function or stub to call. | 
| 5149   int length = instr->hydrogen()->length(); | 5151   int length = instr->hydrogen()->length(); | 
| 5150   if (instr->hydrogen()->IsCopyOnWrite()) { | 5152   if (instr->hydrogen()->IsCopyOnWrite()) { | 
| 5151     ASSERT(instr->hydrogen()->depth() == 1); | 5153     ASSERT(instr->hydrogen()->depth() == 1); | 
| 5152     FastCloneShallowArrayStub::Mode mode = | 5154     FastCloneShallowArrayStub::Mode mode = | 
| 5153         FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS; | 5155         FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS; | 
| 5154     FastCloneShallowArrayStub stub(mode, length); | 5156     FastCloneShallowArrayStub stub(mode, DONT_TRACK_ALLOCATION_SITE, length); | 
| 5155     CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 5157     CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 
| 5156   } else if (instr->hydrogen()->depth() > 1) { | 5158   } else if (instr->hydrogen()->depth() > 1) { | 
| 5157     CallRuntime(Runtime::kCreateArrayLiteral, 3, instr); | 5159     CallRuntime(Runtime::kCreateArrayLiteral, 3, instr); | 
| 5158   } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) { | 5160   } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) { | 
| 5159     CallRuntime(Runtime::kCreateArrayLiteralShallow, 3, instr); | 5161     CallRuntime(Runtime::kCreateArrayLiteralShallow, 3, instr); | 
| 5160   } else { | 5162   } else { | 
| 5161     FastCloneShallowArrayStub::Mode mode = | 5163     FastCloneShallowArrayStub::Mode mode = | 
| 5162         boilerplate_elements_kind == FAST_DOUBLE_ELEMENTS | 5164         boilerplate_elements_kind == FAST_DOUBLE_ELEMENTS | 
| 5163             ? FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS | 5165         ? FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS | 
| 5164             : FastCloneShallowArrayStub::CLONE_ELEMENTS; | 5166         : FastCloneShallowArrayStub::CLONE_ELEMENTS; | 
| 5165     FastCloneShallowArrayStub stub(mode, length); | 5167     FastCloneShallowArrayStub stub(mode, allocation_site_mode, length); | 
| 5166     CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 5168     CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 
| 5167   } | 5169   } | 
| 5168 } | 5170 } | 
| 5169 | 5171 | 
| 5170 | 5172 | 
| 5171 void LCodeGen::EmitDeepCopy(Handle<JSObject> object, | 5173 void LCodeGen::EmitDeepCopy(Handle<JSObject> object, | 
| 5172                             Register result, | 5174                             Register result, | 
| 5173                             Register source, | 5175                             Register source, | 
| 5174                             int* offset) { | 5176                             int* offset, | 
|  | 5177                             AllocationSiteMode mode) { | 
| 5175   ASSERT(!source.is(a2)); | 5178   ASSERT(!source.is(a2)); | 
| 5176   ASSERT(!result.is(a2)); | 5179   ASSERT(!result.is(a2)); | 
| 5177 | 5180 | 
|  | 5181   bool create_allocation_site_info = mode == TRACK_ALLOCATION_SITE && | 
|  | 5182       object->map()->CanTrackAllocationSite(); | 
|  | 5183 | 
| 5178   // Only elements backing stores for non-COW arrays need to be copied. | 5184   // Only elements backing stores for non-COW arrays need to be copied. | 
| 5179   Handle<FixedArrayBase> elements(object->elements()); | 5185   Handle<FixedArrayBase> elements(object->elements()); | 
| 5180   bool has_elements = elements->length() > 0 && | 5186   bool has_elements = elements->length() > 0 && | 
| 5181       elements->map() != isolate()->heap()->fixed_cow_array_map(); | 5187       elements->map() != isolate()->heap()->fixed_cow_array_map(); | 
| 5182 | 5188 | 
| 5183   // Increase the offset so that subsequent objects end up right after | 5189   // Increase the offset so that subsequent objects end up right after | 
| 5184   // this object and its backing store. | 5190   // this object and its backing store. | 
| 5185   int object_offset = *offset; | 5191   int object_offset = *offset; | 
| 5186   int object_size = object->map()->instance_size(); | 5192   int object_size = object->map()->instance_size(); | 
|  | 5193   int elements_size = has_elements ? elements->Size() : 0; | 
| 5187   int elements_offset = *offset + object_size; | 5194   int elements_offset = *offset + object_size; | 
| 5188   int elements_size = has_elements ? elements->Size() : 0; | 5195   if (create_allocation_site_info) { | 
|  | 5196     elements_offset += AllocationSiteInfo::kSize; | 
|  | 5197     *offset += AllocationSiteInfo::kSize; | 
|  | 5198   } | 
|  | 5199 | 
| 5189   *offset += object_size + elements_size; | 5200   *offset += object_size + elements_size; | 
| 5190 | 5201 | 
| 5191   // Copy object header. | 5202   // Copy object header. | 
| 5192   ASSERT(object->properties()->length() == 0); | 5203   ASSERT(object->properties()->length() == 0); | 
| 5193   int inobject_properties = object->map()->inobject_properties(); | 5204   int inobject_properties = object->map()->inobject_properties(); | 
| 5194   int header_size = object_size - inobject_properties * kPointerSize; | 5205   int header_size = object_size - inobject_properties * kPointerSize; | 
| 5195   for (int i = 0; i < header_size; i += kPointerSize) { | 5206   for (int i = 0; i < header_size; i += kPointerSize) { | 
| 5196     if (has_elements && i == JSObject::kElementsOffset) { | 5207     if (has_elements && i == JSObject::kElementsOffset) { | 
| 5197       __ Addu(a2, result, Operand(elements_offset)); | 5208       __ Addu(a2, result, Operand(elements_offset)); | 
| 5198     } else { | 5209     } else { | 
| 5199       __ lw(a2, FieldMemOperand(source, i)); | 5210       __ lw(a2, FieldMemOperand(source, i)); | 
| 5200     } | 5211     } | 
| 5201     __ sw(a2, FieldMemOperand(result, object_offset + i)); | 5212     __ sw(a2, FieldMemOperand(result, object_offset + i)); | 
| 5202   } | 5213   } | 
| 5203 | 5214 | 
| 5204   // Copy in-object properties. | 5215   // Copy in-object properties. | 
| 5205   for (int i = 0; i < inobject_properties; i++) { | 5216   for (int i = 0; i < inobject_properties; i++) { | 
| 5206     int total_offset = object_offset + object->GetInObjectPropertyOffset(i); | 5217     int total_offset = object_offset + object->GetInObjectPropertyOffset(i); | 
| 5207     Handle<Object> value = Handle<Object>(object->InObjectPropertyAt(i)); | 5218     Handle<Object> value = Handle<Object>(object->InObjectPropertyAt(i)); | 
| 5208     if (value->IsJSObject()) { | 5219     if (value->IsJSObject()) { | 
| 5209       Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 5220       Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 
| 5210       __ Addu(a2, result, Operand(*offset)); | 5221       __ Addu(a2, result, Operand(*offset)); | 
| 5211       __ sw(a2, FieldMemOperand(result, total_offset)); | 5222       __ sw(a2, FieldMemOperand(result, total_offset)); | 
| 5212       __ LoadHeapObject(source, value_object); | 5223       __ LoadHeapObject(source, value_object); | 
| 5213       EmitDeepCopy(value_object, result, source, offset); | 5224       EmitDeepCopy(value_object, result, source, offset, | 
|  | 5225                    DONT_TRACK_ALLOCATION_SITE); | 
| 5214     } else if (value->IsHeapObject()) { | 5226     } else if (value->IsHeapObject()) { | 
| 5215       __ LoadHeapObject(a2, Handle<HeapObject>::cast(value)); | 5227       __ LoadHeapObject(a2, Handle<HeapObject>::cast(value)); | 
| 5216       __ sw(a2, FieldMemOperand(result, total_offset)); | 5228       __ sw(a2, FieldMemOperand(result, total_offset)); | 
| 5217     } else { | 5229     } else { | 
| 5218       __ li(a2, Operand(value)); | 5230       __ li(a2, Operand(value)); | 
| 5219       __ sw(a2, FieldMemOperand(result, total_offset)); | 5231       __ sw(a2, FieldMemOperand(result, total_offset)); | 
| 5220     } | 5232     } | 
| 5221   } | 5233   } | 
| 5222 | 5234 | 
|  | 5235   // Build Allocation Site Info if desired | 
|  | 5236   if (create_allocation_site_info) { | 
|  | 5237     __ li(a2, Operand(Handle<Map>(isolate()->heap()-> | 
|  | 5238                                   allocation_site_info_map()))); | 
|  | 5239     __ sw(a2, FieldMemOperand(result, object_size)); | 
|  | 5240     __ sw(source, FieldMemOperand(result, object_size + kPointerSize)); | 
|  | 5241   } | 
| 5223 | 5242 | 
| 5224   if (has_elements) { | 5243   if (has_elements) { | 
| 5225     // Copy elements backing store header. | 5244     // Copy elements backing store header. | 
| 5226     __ LoadHeapObject(source, elements); | 5245     __ LoadHeapObject(source, elements); | 
| 5227     for (int i = 0; i < FixedArray::kHeaderSize; i += kPointerSize) { | 5246     for (int i = 0; i < FixedArray::kHeaderSize; i += kPointerSize) { | 
| 5228       __ lw(a2, FieldMemOperand(source, i)); | 5247       __ lw(a2, FieldMemOperand(source, i)); | 
| 5229       __ sw(a2, FieldMemOperand(result, elements_offset + i)); | 5248       __ sw(a2, FieldMemOperand(result, elements_offset + i)); | 
| 5230     } | 5249     } | 
| 5231 | 5250 | 
| 5232     // Copy elements backing store content. | 5251     // Copy elements backing store content. | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 5249     } else if (elements->IsFixedArray()) { | 5268     } else if (elements->IsFixedArray()) { | 
| 5250       Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); | 5269       Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); | 
| 5251       for (int i = 0; i < elements_length; i++) { | 5270       for (int i = 0; i < elements_length; i++) { | 
| 5252         int total_offset = elements_offset + FixedArray::OffsetOfElementAt(i); | 5271         int total_offset = elements_offset + FixedArray::OffsetOfElementAt(i); | 
| 5253         Handle<Object> value(fast_elements->get(i)); | 5272         Handle<Object> value(fast_elements->get(i)); | 
| 5254         if (value->IsJSObject()) { | 5273         if (value->IsJSObject()) { | 
| 5255           Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 5274           Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 
| 5256           __ Addu(a2, result, Operand(*offset)); | 5275           __ Addu(a2, result, Operand(*offset)); | 
| 5257           __ sw(a2, FieldMemOperand(result, total_offset)); | 5276           __ sw(a2, FieldMemOperand(result, total_offset)); | 
| 5258           __ LoadHeapObject(source, value_object); | 5277           __ LoadHeapObject(source, value_object); | 
| 5259           EmitDeepCopy(value_object, result, source, offset); | 5278           EmitDeepCopy(value_object, result, source, offset, | 
|  | 5279                        DONT_TRACK_ALLOCATION_SITE); | 
| 5260         } else if (value->IsHeapObject()) { | 5280         } else if (value->IsHeapObject()) { | 
| 5261           __ LoadHeapObject(a2, Handle<HeapObject>::cast(value)); | 5281           __ LoadHeapObject(a2, Handle<HeapObject>::cast(value)); | 
| 5262           __ sw(a2, FieldMemOperand(result, total_offset)); | 5282           __ sw(a2, FieldMemOperand(result, total_offset)); | 
| 5263         } else { | 5283         } else { | 
| 5264           __ li(a2, Operand(value)); | 5284           __ li(a2, Operand(value)); | 
| 5265           __ sw(a2, FieldMemOperand(result, total_offset)); | 5285           __ sw(a2, FieldMemOperand(result, total_offset)); | 
| 5266         } | 5286         } | 
| 5267       } | 5287       } | 
| 5268     } else { | 5288     } else { | 
| 5269       UNREACHABLE(); | 5289       UNREACHABLE(); | 
| (...skipping 30 matching lines...) Expand all  Loading... | 
| 5300   __ jmp(&allocated); | 5320   __ jmp(&allocated); | 
| 5301 | 5321 | 
| 5302   __ bind(&runtime_allocate); | 5322   __ bind(&runtime_allocate); | 
| 5303   __ li(a0, Operand(Smi::FromInt(size))); | 5323   __ li(a0, Operand(Smi::FromInt(size))); | 
| 5304   __ push(a0); | 5324   __ push(a0); | 
| 5305   CallRuntime(Runtime::kAllocateInNewSpace, 1, instr); | 5325   CallRuntime(Runtime::kAllocateInNewSpace, 1, instr); | 
| 5306 | 5326 | 
| 5307   __ bind(&allocated); | 5327   __ bind(&allocated); | 
| 5308   int offset = 0; | 5328   int offset = 0; | 
| 5309   __ LoadHeapObject(a1, instr->hydrogen()->boilerplate()); | 5329   __ LoadHeapObject(a1, instr->hydrogen()->boilerplate()); | 
| 5310   EmitDeepCopy(instr->hydrogen()->boilerplate(), v0, a1, &offset); | 5330   EmitDeepCopy(instr->hydrogen()->boilerplate(), v0, a1, &offset, | 
|  | 5331                instr->hydrogen()->allocation_site_mode()); | 
| 5311   ASSERT_EQ(size, offset); | 5332   ASSERT_EQ(size, offset); | 
| 5312 } | 5333 } | 
| 5313 | 5334 | 
| 5314 | 5335 | 
| 5315 void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { | 5336 void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { | 
| 5316   ASSERT(ToRegister(instr->result()).is(v0)); | 5337   ASSERT(ToRegister(instr->result()).is(v0)); | 
| 5317   Handle<FixedArray> literals(instr->environment()->closure()->literals()); | 5338   Handle<FixedArray> literals(instr->environment()->closure()->literals()); | 
| 5318   Handle<FixedArray> constant_properties = | 5339   Handle<FixedArray> constant_properties = | 
| 5319       instr->hydrogen()->constant_properties(); | 5340       instr->hydrogen()->constant_properties(); | 
| 5320 | 5341 | 
| (...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 5807   __ Subu(scratch, result, scratch); | 5828   __ Subu(scratch, result, scratch); | 
| 5808   __ lw(result, FieldMemOperand(scratch, | 5829   __ lw(result, FieldMemOperand(scratch, | 
| 5809                                 FixedArray::kHeaderSize - kPointerSize)); | 5830                                 FixedArray::kHeaderSize - kPointerSize)); | 
| 5810   __ bind(&done); | 5831   __ bind(&done); | 
| 5811 } | 5832 } | 
| 5812 | 5833 | 
| 5813 | 5834 | 
| 5814 #undef __ | 5835 #undef __ | 
| 5815 | 5836 | 
| 5816 } }  // namespace v8::internal | 5837 } }  // namespace v8::internal | 
| OLD | NEW | 
|---|