| Index: src/hydrogen.cc
|
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc
|
| index bb56296a22def95346c2a2379d7cd3811300c7bb..f68f8aabc146f86dbaf0066722d0025a9dc92973 100644
|
| --- a/src/hydrogen.cc
|
| +++ b/src/hydrogen.cc
|
| @@ -1462,6 +1462,123 @@ void HGraphBuilder::BuildCopyElements(HValue* context,
|
| }
|
|
|
|
|
| +HValue* HGraphBuilder::BuildCloneShallowArray(HContext* context,
|
| + HValue* boilerplate,
|
| + AllocationSiteMode mode,
|
| + ElementsKind kind,
|
| + BailoutId id,
|
| + int length) {
|
| + Zone* zone = this->zone();
|
| + Factory* factory = isolate()->factory();
|
| +
|
| + // All sizes here are multiples of kPointerSize.
|
| + int size = JSArray::kSize;
|
| + if (mode == TRACK_ALLOCATION_SITE) {
|
| + size += AllocationSiteInfo::kSize;
|
| + }
|
| + int elems_offset = size;
|
| + if (length > 0) {
|
| + size += IsFastDoubleElementsKind(kind)
|
| + ? FixedDoubleArray::SizeFor(length)
|
| + : FixedArray::SizeFor(length);
|
| + }
|
| +
|
| + HAllocate::Flags allocate_flags = HAllocate::CAN_ALLOCATE_IN_NEW_SPACE;
|
| + if (IsFastDoubleElementsKind(kind)) {
|
| + allocate_flags = static_cast<HAllocate::Flags>(
|
| + allocate_flags | HAllocate::ALLOCATE_DOUBLE_ALIGNED);
|
| + }
|
| +
|
| + // Allocate both the JS array and the elements array in one big
|
| + // allocation. This avoids multiple limit checks.
|
| + HValue* size_in_bytes =
|
| + AddInstruction(new(zone) HConstant(size, Representation::Integer32()));
|
| + HInstruction* object =
|
| + AddInstruction(new(zone) HAllocate(context,
|
| + size_in_bytes,
|
| + HType::JSObject(),
|
| + allocate_flags));
|
| +
|
| + // Copy the JS array part.
|
| + for (int i = 0; i < JSArray::kSize; i += kPointerSize) {
|
| + if ((i != JSArray::kElementsOffset) || (length == 0)) {
|
| + HInstruction* value =
|
| + AddInstruction(new(zone) HLoadNamedField(boilerplate, true, i));
|
| + if (i != JSArray::kMapOffset) {
|
| + AddInstruction(new(zone) HStoreNamedField(object,
|
| + factory->empty_string(),
|
| + value,
|
| + true, i));
|
| + AddSimulate(id);
|
| + } else {
|
| + BuildStoreMap(object, value, id);
|
| + }
|
| + }
|
| + }
|
| +
|
| + // Create an allocation site info if requested.
|
| + if (mode == TRACK_ALLOCATION_SITE) {
|
| + HValue* alloc_site =
|
| + AddInstruction(new(zone) HInnerAllocatedObject(object, JSArray::kSize));
|
| + Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map());
|
| + BuildStoreMap(alloc_site, alloc_site_map, id);
|
| + int alloc_payload_offset = AllocationSiteInfo::kPayloadOffset;
|
| + AddInstruction(new(zone) HStoreNamedField(alloc_site,
|
| + factory->empty_string(),
|
| + boilerplate,
|
| + true, alloc_payload_offset));
|
| + AddSimulate(id);
|
| + }
|
| +
|
| + if (length > 0) {
|
| + // Get hold of the elements array of the boilerplate and setup the
|
| + // elements pointer in the resulting object.
|
| + HValue* boilerplate_elements =
|
| + AddInstruction(new(zone) HLoadElements(boilerplate, NULL));
|
| + HValue* object_elements =
|
| + AddInstruction(new(zone) HInnerAllocatedObject(object, elems_offset));
|
| + AddInstruction(new(zone) HStoreNamedField(object,
|
| + factory->elements_field_string(),
|
| + object_elements,
|
| + true, JSObject::kElementsOffset));
|
| + AddSimulate(id);
|
| +
|
| + // Copy the elements array header.
|
| + for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) {
|
| + HInstruction* value =
|
| + AddInstruction(new(zone) HLoadNamedField(boilerplate_elements,
|
| + true, i));
|
| + AddInstruction(new(zone) HStoreNamedField(object_elements,
|
| + factory->empty_string(),
|
| + value,
|
| + true, i));
|
| + AddSimulate(id);
|
| + }
|
| +
|
| + // Copy the elements array contents.
|
| + // TODO(mstarzinger): Teach HGraphBuilder::BuildCopyElements to unfold
|
| + // copying loops with constant length up to a given boundary and use this
|
| + // helper here instead.
|
| + for (int i = 0; i < length; i++) {
|
| + HValue* key_constant =
|
| + AddInstruction(new(zone) HConstant(i, Representation::Integer32()));
|
| + HInstruction* value =
|
| + AddInstruction(new(zone) HLoadKeyed(boilerplate_elements,
|
| + key_constant,
|
| + NULL,
|
| + kind));
|
| + AddInstruction(new(zone) HStoreKeyed(object_elements,
|
| + key_constant,
|
| + value,
|
| + kind));
|
| + AddSimulate(id);
|
| + }
|
| + }
|
| +
|
| + return object;
|
| +}
|
| +
|
| +
|
| HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info,
|
| TypeFeedbackOracle* oracle)
|
| : HGraphBuilder(info),
|
|
|