| 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 4885 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  4896   __ Push(Smi::FromInt(instance_size)); |  4896   __ Push(Smi::FromInt(instance_size)); | 
|  4897   CallRuntimeFromDeferred(Runtime::kAllocateInNewSpace, 1, instr); |  4897   CallRuntimeFromDeferred(Runtime::kAllocateInNewSpace, 1, instr); | 
|  4898   __ StoreToSafepointRegisterSlot(result, rax); |  4898   __ StoreToSafepointRegisterSlot(result, rax); | 
|  4899 } |  4899 } | 
|  4900  |  4900  | 
|  4901  |  4901  | 
|  4902 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { |  4902 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { | 
|  4903   Handle<FixedArray> literals(instr->environment()->closure()->literals()); |  4903   Handle<FixedArray> literals(instr->environment()->closure()->literals()); | 
|  4904   ElementsKind boilerplate_elements_kind = |  4904   ElementsKind boilerplate_elements_kind = | 
|  4905       instr->hydrogen()->boilerplate_elements_kind(); |  4905       instr->hydrogen()->boilerplate_elements_kind(); | 
 |  4906   AllocationSiteInfoMode allocation_site_info_mode = instr->hydrogen()-> | 
 |  4907       allocation_site_info_mode(); | 
|  4906  |  4908  | 
|  4907   // Deopt if the array literal boilerplate ElementsKind is of a type different |  4909   // Deopt if the array literal boilerplate ElementsKind is of a type different | 
|  4908   // than the expected one. The check isn't necessary if the boilerplate has |  4910   // than the expected one. The check isn't necessary if the boilerplate has | 
|  4909   // already been converted to TERMINAL_FAST_ELEMENTS_KIND. |  4911   // already been converted to TERMINAL_FAST_ELEMENTS_KIND. | 
|  4910   if (CanTransitionToMoreGeneralFastElementsKind( |  4912   if (CanTransitionToMoreGeneralFastElementsKind( | 
|  4911           boilerplate_elements_kind, true)) { |  4913           boilerplate_elements_kind, true)) { | 
|  4912     __ LoadHeapObject(rax, instr->hydrogen()->boilerplate_object()); |  4914     __ LoadHeapObject(rax, instr->hydrogen()->boilerplate_object()); | 
|  4913     __ movq(rbx, FieldOperand(rax, HeapObject::kMapOffset)); |  4915     __ movq(rbx, FieldOperand(rax, HeapObject::kMapOffset)); | 
|  4914     // Load the map's "bit field 2". |  4916     // Load the map's "bit field 2". | 
|  4915     __ movb(rbx, FieldOperand(rbx, Map::kBitField2Offset)); |  4917     __ movb(rbx, FieldOperand(rbx, Map::kBitField2Offset)); | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
|  4926   // Boilerplate already exists, constant elements are never accessed. |  4928   // Boilerplate already exists, constant elements are never accessed. | 
|  4927   // Pass an empty fixed array. |  4929   // Pass an empty fixed array. | 
|  4928   __ Push(isolate()->factory()->empty_fixed_array()); |  4930   __ Push(isolate()->factory()->empty_fixed_array()); | 
|  4929  |  4931  | 
|  4930   // Pick the right runtime function or stub to call. |  4932   // Pick the right runtime function or stub to call. | 
|  4931   int length = instr->hydrogen()->length(); |  4933   int length = instr->hydrogen()->length(); | 
|  4932   if (instr->hydrogen()->IsCopyOnWrite()) { |  4934   if (instr->hydrogen()->IsCopyOnWrite()) { | 
|  4933     ASSERT(instr->hydrogen()->depth() == 1); |  4935     ASSERT(instr->hydrogen()->depth() == 1); | 
|  4934     FastCloneShallowArrayStub::Mode mode = |  4936     FastCloneShallowArrayStub::Mode mode = | 
|  4935         FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS; |  4937         FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS; | 
|  4936     FastCloneShallowArrayStub stub(mode, length); |  4938     FastCloneShallowArrayStub stub(mode, DONT_TRACK_ALLOCATION_SITE_INFO, | 
 |  4939                                    length); | 
|  4937     CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |  4940     CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 
|  4938   } else if (instr->hydrogen()->depth() > 1) { |  4941   } else if (instr->hydrogen()->depth() > 1) { | 
|  4939     CallRuntime(Runtime::kCreateArrayLiteral, 3, instr); |  4942     CallRuntime(Runtime::kCreateArrayLiteral, 3, instr); | 
|  4940   } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) { |  4943   } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) { | 
|  4941     CallRuntime(Runtime::kCreateArrayLiteralShallow, 3, instr); |  4944     CallRuntime(Runtime::kCreateArrayLiteralShallow, 3, instr); | 
|  4942   } else { |  4945   } else { | 
|  4943     FastCloneShallowArrayStub::Mode mode = |  4946     FastCloneShallowArrayStub::Mode mode = | 
|  4944         boilerplate_elements_kind == FAST_DOUBLE_ELEMENTS |  4947         boilerplate_elements_kind == FAST_DOUBLE_ELEMENTS | 
|  4945             ? FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS |  4948         ? FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS | 
|  4946             : FastCloneShallowArrayStub::CLONE_ELEMENTS; |  4949         : FastCloneShallowArrayStub::CLONE_ELEMENTS; | 
|  4947     FastCloneShallowArrayStub stub(mode, length); |  4950     FastCloneShallowArrayStub stub(mode, allocation_site_info_mode, length); | 
|  4948     CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |  4951     CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 
|  4949   } |  4952   } | 
|  4950 } |  4953 } | 
|  4951  |  4954  | 
|  4952  |  4955  | 
|  4953 void LCodeGen::EmitDeepCopy(Handle<JSObject> object, |  4956 void LCodeGen::EmitDeepCopy(Handle<JSObject> object, | 
|  4954                             Register result, |  4957                             Register result, | 
|  4955                             Register source, |  4958                             Register source, | 
|  4956                             int* offset) { |  4959                             int* offset, | 
 |  4960                             AllocationSiteInfoMode mode) { | 
|  4957   ASSERT(!source.is(rcx)); |  4961   ASSERT(!source.is(rcx)); | 
|  4958   ASSERT(!result.is(rcx)); |  4962   ASSERT(!result.is(rcx)); | 
|  4959  |  4963  | 
 |  4964   bool create_allocation_site_info = mode == TRACK_ALLOCATION_SITE_INFO && | 
 |  4965       object->map()->CanTrackAllocationSite(); | 
 |  4966  | 
|  4960   // Only elements backing stores for non-COW arrays need to be copied. |  4967   // Only elements backing stores for non-COW arrays need to be copied. | 
|  4961   Handle<FixedArrayBase> elements(object->elements()); |  4968   Handle<FixedArrayBase> elements(object->elements()); | 
|  4962   bool has_elements = elements->length() > 0 && |  4969   bool has_elements = elements->length() > 0 && | 
|  4963       elements->map() != isolate()->heap()->fixed_cow_array_map(); |  4970       elements->map() != isolate()->heap()->fixed_cow_array_map(); | 
|  4964  |  4971  | 
|  4965   // Increase the offset so that subsequent objects end up right after |  4972   // Increase the offset so that subsequent objects end up right after | 
|  4966   // this object and its backing store. |  4973   // this object and its backing store. | 
|  4967   int object_offset = *offset; |  4974   int object_offset = *offset; | 
|  4968   int object_size = object->map()->instance_size(); |  4975   int object_size = object->map()->instance_size(); | 
|  4969   int elements_offset = *offset + object_size; |  4976   int elements_offset = *offset + object_size; | 
 |  4977   if (create_allocation_site_info) { | 
 |  4978     elements_offset += AllocationSiteInfo::kSize; | 
 |  4979   } | 
|  4970   int elements_size = has_elements ? elements->Size() : 0; |  4980   int elements_size = has_elements ? elements->Size() : 0; | 
|  4971   *offset += object_size + elements_size; |  4981   *offset += object_size + elements_size; | 
 |  4982   if (create_allocation_site_info) { | 
 |  4983     *offset += AllocationSiteInfo::kSize; | 
 |  4984   } | 
|  4972  |  4985  | 
|  4973   // Copy object header. |  4986   // Copy object header. | 
|  4974   ASSERT(object->properties()->length() == 0); |  4987   ASSERT(object->properties()->length() == 0); | 
|  4975   int inobject_properties = object->map()->inobject_properties(); |  4988   int inobject_properties = object->map()->inobject_properties(); | 
|  4976   int header_size = object_size - inobject_properties * kPointerSize; |  4989   int header_size = object_size - inobject_properties * kPointerSize; | 
|  4977   for (int i = 0; i < header_size; i += kPointerSize) { |  4990   for (int i = 0; i < header_size; i += kPointerSize) { | 
|  4978     if (has_elements && i == JSObject::kElementsOffset) { |  4991     if (has_elements && i == JSObject::kElementsOffset) { | 
|  4979       __ lea(rcx, Operand(result, elements_offset)); |  4992       __ lea(rcx, Operand(result, elements_offset)); | 
|  4980     } else { |  4993     } else { | 
|  4981       __ movq(rcx, FieldOperand(source, i)); |  4994       __ movq(rcx, FieldOperand(source, i)); | 
|  4982     } |  4995     } | 
|  4983     __ movq(FieldOperand(result, object_offset + i), rcx); |  4996     __ movq(FieldOperand(result, object_offset + i), rcx); | 
|  4984   } |  4997   } | 
|  4985  |  4998  | 
|  4986   // Copy in-object properties. |  4999   // Copy in-object properties. | 
|  4987   for (int i = 0; i < inobject_properties; i++) { |  5000   for (int i = 0; i < inobject_properties; i++) { | 
|  4988     int total_offset = object_offset + object->GetInObjectPropertyOffset(i); |  5001     int total_offset = object_offset + object->GetInObjectPropertyOffset(i); | 
|  4989     Handle<Object> value = Handle<Object>(object->InObjectPropertyAt(i)); |  5002     Handle<Object> value = Handle<Object>(object->InObjectPropertyAt(i)); | 
|  4990     if (value->IsJSObject()) { |  5003     if (value->IsJSObject()) { | 
|  4991       Handle<JSObject> value_object = Handle<JSObject>::cast(value); |  5004       Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 
|  4992       __ lea(rcx, Operand(result, *offset)); |  5005       __ lea(rcx, Operand(result, *offset)); | 
|  4993       __ movq(FieldOperand(result, total_offset), rcx); |  5006       __ movq(FieldOperand(result, total_offset), rcx); | 
|  4994       __ LoadHeapObject(source, value_object); |  5007       __ LoadHeapObject(source, value_object); | 
|  4995       EmitDeepCopy(value_object, result, source, offset); |  5008       EmitDeepCopy(value_object, result, source, offset, | 
 |  5009                    DONT_TRACK_ALLOCATION_SITE_INFO); | 
|  4996     } else if (value->IsHeapObject()) { |  5010     } else if (value->IsHeapObject()) { | 
|  4997       __ LoadHeapObject(rcx, Handle<HeapObject>::cast(value)); |  5011       __ LoadHeapObject(rcx, Handle<HeapObject>::cast(value)); | 
|  4998       __ movq(FieldOperand(result, total_offset), rcx); |  5012       __ movq(FieldOperand(result, total_offset), rcx); | 
|  4999     } else { |  5013     } else { | 
|  5000       __ movq(rcx, value, RelocInfo::NONE64); |  5014       __ movq(rcx, value, RelocInfo::NONE64); | 
|  5001       __ movq(FieldOperand(result, total_offset), rcx); |  5015       __ movq(FieldOperand(result, total_offset), rcx); | 
|  5002     } |  5016     } | 
|  5003   } |  5017   } | 
|  5004  |  5018  | 
 |  5019   // Build Allocation Site Info if desired | 
 |  5020   if (create_allocation_site_info) { | 
 |  5021     __ LoadRoot(kScratchRegister, Heap::kAllocationSiteInfoMapRootIndex); | 
 |  5022     __ movq(FieldOperand(result, object_size), kScratchRegister); | 
 |  5023     __ movq(FieldOperand(result, object_size + kPointerSize), source); | 
 |  5024   } | 
 |  5025  | 
|  5005   if (has_elements) { |  5026   if (has_elements) { | 
|  5006     // Copy elements backing store header. |  5027     // Copy elements backing store header. | 
|  5007     __ LoadHeapObject(source, elements); |  5028     __ LoadHeapObject(source, elements); | 
|  5008     for (int i = 0; i < FixedArray::kHeaderSize; i += kPointerSize) { |  5029     for (int i = 0; i < FixedArray::kHeaderSize; i += kPointerSize) { | 
|  5009       __ movq(rcx, FieldOperand(source, i)); |  5030       __ movq(rcx, FieldOperand(source, i)); | 
|  5010       __ movq(FieldOperand(result, elements_offset + i), rcx); |  5031       __ movq(FieldOperand(result, elements_offset + i), rcx); | 
|  5011     } |  5032     } | 
|  5012  |  5033  | 
|  5013     // Copy elements backing store content. |  5034     // Copy elements backing store content. | 
|  5014     int elements_length = elements->length(); |  5035     int elements_length = elements->length(); | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
|  5025     } else if (elements->IsFixedArray()) { |  5046     } else if (elements->IsFixedArray()) { | 
|  5026       Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); |  5047       Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); | 
|  5027       for (int i = 0; i < elements_length; i++) { |  5048       for (int i = 0; i < elements_length; i++) { | 
|  5028         int total_offset = elements_offset + FixedArray::OffsetOfElementAt(i); |  5049         int total_offset = elements_offset + FixedArray::OffsetOfElementAt(i); | 
|  5029         Handle<Object> value(fast_elements->get(i)); |  5050         Handle<Object> value(fast_elements->get(i)); | 
|  5030         if (value->IsJSObject()) { |  5051         if (value->IsJSObject()) { | 
|  5031           Handle<JSObject> value_object = Handle<JSObject>::cast(value); |  5052           Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 
|  5032           __ lea(rcx, Operand(result, *offset)); |  5053           __ lea(rcx, Operand(result, *offset)); | 
|  5033           __ movq(FieldOperand(result, total_offset), rcx); |  5054           __ movq(FieldOperand(result, total_offset), rcx); | 
|  5034           __ LoadHeapObject(source, value_object); |  5055           __ LoadHeapObject(source, value_object); | 
|  5035           EmitDeepCopy(value_object, result, source, offset); |  5056           EmitDeepCopy(value_object, result, source, offset, | 
 |  5057                        DONT_TRACK_ALLOCATION_SITE_INFO); | 
|  5036         } else if (value->IsHeapObject()) { |  5058         } else if (value->IsHeapObject()) { | 
|  5037           __ LoadHeapObject(rcx, Handle<HeapObject>::cast(value)); |  5059           __ LoadHeapObject(rcx, Handle<HeapObject>::cast(value)); | 
|  5038           __ movq(FieldOperand(result, total_offset), rcx); |  5060           __ movq(FieldOperand(result, total_offset), rcx); | 
|  5039         } else { |  5061         } else { | 
|  5040           __ movq(rcx, value, RelocInfo::NONE64); |  5062           __ movq(rcx, value, RelocInfo::NONE64); | 
|  5041           __ movq(FieldOperand(result, total_offset), rcx); |  5063           __ movq(FieldOperand(result, total_offset), rcx); | 
|  5042         } |  5064         } | 
|  5043       } |  5065       } | 
|  5044     } else { |  5066     } else { | 
|  5045       UNREACHABLE(); |  5067       UNREACHABLE(); | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
|  5075   __ AllocateInNewSpace(size, rax, rcx, rdx, &runtime_allocate, TAG_OBJECT); |  5097   __ AllocateInNewSpace(size, rax, rcx, rdx, &runtime_allocate, TAG_OBJECT); | 
|  5076   __ jmp(&allocated); |  5098   __ jmp(&allocated); | 
|  5077  |  5099  | 
|  5078   __ bind(&runtime_allocate); |  5100   __ bind(&runtime_allocate); | 
|  5079   __ Push(Smi::FromInt(size)); |  5101   __ Push(Smi::FromInt(size)); | 
|  5080   CallRuntime(Runtime::kAllocateInNewSpace, 1, instr); |  5102   CallRuntime(Runtime::kAllocateInNewSpace, 1, instr); | 
|  5081  |  5103  | 
|  5082   __ bind(&allocated); |  5104   __ bind(&allocated); | 
|  5083   int offset = 0; |  5105   int offset = 0; | 
|  5084   __ LoadHeapObject(rbx, instr->hydrogen()->boilerplate()); |  5106   __ LoadHeapObject(rbx, instr->hydrogen()->boilerplate()); | 
|  5085   EmitDeepCopy(instr->hydrogen()->boilerplate(), rax, rbx, &offset); |  5107   EmitDeepCopy(instr->hydrogen()->boilerplate(), rax, rbx, &offset, | 
 |  5108                instr->hydrogen()->allocation_site_info_mode()); | 
|  5086   ASSERT_EQ(size, offset); |  5109   ASSERT_EQ(size, offset); | 
|  5087 } |  5110 } | 
|  5088  |  5111  | 
|  5089  |  5112  | 
|  5090 void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { |  5113 void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { | 
|  5091   Handle<FixedArray> literals(instr->environment()->closure()->literals()); |  5114   Handle<FixedArray> literals(instr->environment()->closure()->literals()); | 
|  5092   Handle<FixedArray> constant_properties = |  5115   Handle<FixedArray> constant_properties = | 
|  5093       instr->hydrogen()->constant_properties(); |  5116       instr->hydrogen()->constant_properties(); | 
|  5094  |  5117  | 
|  5095   // Set up the parameters to the stub/runtime call. |  5118   // Set up the parameters to the stub/runtime call. | 
| (...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  5553                                FixedArray::kHeaderSize - kPointerSize)); |  5576                                FixedArray::kHeaderSize - kPointerSize)); | 
|  5554   __ bind(&done); |  5577   __ bind(&done); | 
|  5555 } |  5578 } | 
|  5556  |  5579  | 
|  5557  |  5580  | 
|  5558 #undef __ |  5581 #undef __ | 
|  5559  |  5582  | 
|  5560 } }  // namespace v8::internal |  5583 } }  // namespace v8::internal | 
|  5561  |  5584  | 
|  5562 #endif  // V8_TARGET_ARCH_X64 |  5585 #endif  // V8_TARGET_ARCH_X64 | 
| OLD | NEW |