Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(114)

Side by Side Diff: src/hydrogen.cc

Issue 61463005: Supported folding of constant size allocation followed by dynamic size allocation. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebasing Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 2118 matching lines...) Expand 10 before | Expand all | Expand 10 after
2129 elements, isolate()->factory()->fixed_array_map(), top_info()); 2129 elements, isolate()->factory()->fixed_array_map(), top_info());
2130 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); 2130 check_cow_map->ClearGVNFlag(kDependsOnElementsKind);
2131 } 2131 }
2132 } 2132 }
2133 } 2133 }
2134 return AddElementAccess(elements, checked_key, val, checked_object, 2134 return AddElementAccess(elements, checked_key, val, checked_object,
2135 elements_kind, is_store, load_mode); 2135 elements_kind, is_store, load_mode);
2136 } 2136 }
2137 2137
2138 2138
2139
2140 HValue* HGraphBuilder::BuildAllocateArrayFromLength( 2139 HValue* HGraphBuilder::BuildAllocateArrayFromLength(
2141 JSArrayBuilder* array_builder, 2140 JSArrayBuilder* array_builder,
2142 HValue* length_argument) { 2141 HValue* length_argument) {
2143 if (length_argument->IsConstant() && 2142 if (length_argument->IsConstant() &&
2144 HConstant::cast(length_argument)->HasSmiValue()) { 2143 HConstant::cast(length_argument)->HasSmiValue()) {
2145 int array_length = HConstant::cast(length_argument)->Integer32Value(); 2144 int array_length = HConstant::cast(length_argument)->Integer32Value();
2146 HValue* new_object = array_length == 0 2145 HValue* new_object = array_length == 0
2147 ? array_builder->AllocateEmptyArray() 2146 ? array_builder->AllocateEmptyArray()
2148 : array_builder->AllocateArray(length_argument, length_argument); 2147 : array_builder->AllocateArray(length_argument, length_argument);
2149 return new_object; 2148 return new_object;
(...skipping 22 matching lines...) Expand all
2172 Push(checked_length); // length 2171 Push(checked_length); // length
2173 } 2172 }
2174 if_builder.End(); 2173 if_builder.End();
2175 2174
2176 // Figure out total size 2175 // Figure out total size
2177 HValue* length = Pop(); 2176 HValue* length = Pop();
2178 HValue* capacity = Pop(); 2177 HValue* capacity = Pop();
2179 return array_builder->AllocateArray(capacity, length); 2178 return array_builder->AllocateArray(capacity, length);
2180 } 2179 }
2181 2180
2182 HValue* HGraphBuilder::BuildAllocateElements(ElementsKind kind, 2181 HValue* HGraphBuilder::BuildCalculateElementsSize(ElementsKind kind,
2183 HValue* capacity) { 2182 HValue* capacity) {
2184 int elements_size; 2183 int elements_size = IsFastDoubleElementsKind(kind)
2185 InstanceType instance_type; 2184 ? kDoubleSize
2186 2185 : kPointerSize;
2187 if (IsFastDoubleElementsKind(kind)) {
2188 elements_size = kDoubleSize;
2189 instance_type = FIXED_DOUBLE_ARRAY_TYPE;
2190 } else {
2191 elements_size = kPointerSize;
2192 instance_type = FIXED_ARRAY_TYPE;
2193 }
2194 2186
2195 HConstant* elements_size_value = Add<HConstant>(elements_size); 2187 HConstant* elements_size_value = Add<HConstant>(elements_size);
2196 HValue* mul = AddUncasted<HMul>(capacity, elements_size_value); 2188 HInstruction* mul = HMul::NewImul(zone(), context(),
2189 capacity->ActualValue(),
2190 elements_size_value);
2191 AddInstruction(mul);
2197 mul->ClearFlag(HValue::kCanOverflow); 2192 mul->ClearFlag(HValue::kCanOverflow);
2198 2193
2194 STATIC_ASSERT(FixedDoubleArray::kHeaderSize == FixedArray::kHeaderSize);
2195
2199 HConstant* header_size = Add<HConstant>(FixedArray::kHeaderSize); 2196 HConstant* header_size = Add<HConstant>(FixedArray::kHeaderSize);
2200 HValue* total_size = AddUncasted<HAdd>(mul, header_size); 2197 HValue* total_size = AddUncasted<HAdd>(mul, header_size);
2201 total_size->ClearFlag(HValue::kCanOverflow); 2198 total_size->ClearFlag(HValue::kCanOverflow);
2199 return total_size;
2200 }
2202 2201
2203 return Add<HAllocate>(total_size, HType::JSArray(), 2202 HValue* HGraphBuilder::BuildAllocateElements(ElementsKind kind,
2204 isolate()->heap()->GetPretenureMode(), instance_type); 2203 HValue* size_in_bytes,
2204 PretenureFlag pretenure) {
2205 InstanceType instance_type = IsFastDoubleElementsKind(kind)
2206 ? FIXED_DOUBLE_ARRAY_TYPE
2207 : FIXED_ARRAY_TYPE;
2208
2209 return Add<HAllocate>(size_in_bytes, HType::JSArray(),
2210 pretenure, instance_type);
2205 } 2211 }
2206 2212
2207 2213
2208 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements, 2214 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements,
2209 ElementsKind kind, 2215 ElementsKind kind,
2210 HValue* capacity) { 2216 HValue* capacity) {
2211 Factory* factory = isolate()->factory(); 2217 Factory* factory = isolate()->factory();
2212 Handle<Map> map = IsFastDoubleElementsKind(kind) 2218 Handle<Map> map = IsFastDoubleElementsKind(kind)
2213 ? factory->fixed_double_array_map() 2219 ? factory->fixed_double_array_map()
2214 : factory->fixed_array_map(); 2220 : factory->fixed_array_map();
2215 2221
2216 AddStoreMapConstant(elements, map); 2222 AddStoreMapConstant(elements, map);
2217 Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(), 2223 Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(),
2218 capacity); 2224 capacity);
2219 } 2225 }
2220 2226
2221 2227
2222 HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader( 2228 HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader(
2223 ElementsKind kind, 2229 ElementsKind kind,
2224 HValue* capacity) { 2230 HValue* capacity) {
2225 // The HForceRepresentation is to prevent possible deopt on int-smi 2231 // The HForceRepresentation is to prevent possible deopt on int-smi
2226 // conversion after allocation but before the new object fields are set. 2232 // conversion after allocation but before the new object fields are set.
2227 capacity = AddUncasted<HForceRepresentation>(capacity, Representation::Smi()); 2233 capacity = AddUncasted<HForceRepresentation>(capacity, Representation::Smi());
2228 HValue* new_elements = BuildAllocateElements(kind, capacity); 2234 HValue* size_in_bytes = BuildCalculateElementsSize(kind, capacity);
2235 HValue* new_elements = BuildAllocateElements(
2236 kind, size_in_bytes, isolate()->heap()->GetPretenureMode());
2229 BuildInitializeElementsHeader(new_elements, kind, capacity); 2237 BuildInitializeElementsHeader(new_elements, kind, capacity);
2230 return new_elements; 2238 return new_elements;
2231 } 2239 }
2232 2240
2233 2241
2234 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array, 2242 void HGraphBuilder::BuildJSArrayHeader(HValue* array,
2235 HValue* array_map, 2243 HValue* array_map,
2236 AllocationSiteMode mode, 2244 AllocationSiteMode mode,
2237 ElementsKind elements_kind, 2245 ElementsKind elements_kind,
2238 HValue* allocation_site_payload, 2246 HValue* allocation_site_payload,
2239 HValue* length_field) { 2247 HValue* length_field) {
2240
2241 Add<HStoreNamedField>(array, HObjectAccess::ForMap(), array_map); 2248 Add<HStoreNamedField>(array, HObjectAccess::ForMap(), array_map);
2242 2249
2243 HConstant* empty_fixed_array = 2250 HConstant* empty_fixed_array =
2244 Add<HConstant>(isolate()->factory()->empty_fixed_array()); 2251 Add<HConstant>(isolate()->factory()->empty_fixed_array());
2245 2252
2246 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); 2253 Add<HStoreNamedField>(
2247 Add<HStoreNamedField>(array, access, empty_fixed_array); 2254 array, HObjectAccess::ForPropertiesPointer(), empty_fixed_array);
2248 Add<HStoreNamedField>(array, HObjectAccess::ForArrayLength(elements_kind), 2255
2249 length_field); 2256 Add<HStoreNamedField>(
2257 array, HObjectAccess::ForElementsPointer(), empty_fixed_array);
2258
2259 Add<HStoreNamedField>(
2260 array, HObjectAccess::ForArrayLength(elements_kind), length_field);
2250 2261
2251 if (mode == TRACK_ALLOCATION_SITE) { 2262 if (mode == TRACK_ALLOCATION_SITE) {
2252 BuildCreateAllocationMemento(array, 2263 BuildCreateAllocationMemento(array,
2253 JSArray::kSize, 2264 JSArray::kSize,
2254 allocation_site_payload); 2265 allocation_site_payload);
2255 } 2266 }
2256
2257 int elements_location = JSArray::kSize;
2258 if (mode == TRACK_ALLOCATION_SITE) {
2259 elements_location += AllocationMemento::kSize;
2260 }
2261
2262 HValue* elements = Add<HInnerAllocatedObject>(array, elements_location);
2263 Add<HStoreNamedField>(array, HObjectAccess::ForElementsPointer(), elements);
2264 return static_cast<HInnerAllocatedObject*>(elements);
2265 } 2267 }
2266 2268
2267 2269
2268 HInstruction* HGraphBuilder::AddElementAccess( 2270 HInstruction* HGraphBuilder::AddElementAccess(
2269 HValue* elements, 2271 HValue* elements,
2270 HValue* checked_key, 2272 HValue* checked_key,
2271 HValue* val, 2273 HValue* val,
2272 HValue* dependency, 2274 HValue* dependency,
2273 ElementsKind elements_kind, 2275 ElementsKind elements_kind,
2274 bool is_store, 2276 bool is_store,
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after
2672 } 2674 }
2673 2675
2674 2676
2675 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { 2677 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() {
2676 // Find the map near the constructor function 2678 // Find the map near the constructor function
2677 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); 2679 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
2678 return builder()->AddLoadNamedField(constructor_function_, access); 2680 return builder()->AddLoadNamedField(constructor_function_, access);
2679 } 2681 }
2680 2682
2681 2683
2682 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( 2684 HValue* HGraphBuilder::JSArrayBuilder::EstablishHeaderAllocationSize() {
2683 HValue* length_node) {
2684 ASSERT(length_node != NULL);
2685
2686 int base_size = JSArray::kSize; 2685 int base_size = JSArray::kSize;
2687 if (mode_ == TRACK_ALLOCATION_SITE) { 2686 if (mode_ == TRACK_ALLOCATION_SITE) {
2688 base_size += AllocationMemento::kSize; 2687 base_size += AllocationMemento::kSize;
2689 } 2688 }
2690
2691 STATIC_ASSERT(FixedDoubleArray::kHeaderSize == FixedArray::kHeaderSize);
2692 base_size += FixedArray::kHeaderSize;
2693
2694 HInstruction* elements_size_value =
2695 builder()->Add<HConstant>(elements_size());
2696 HInstruction* mul = HMul::NewImul(builder()->zone(), builder()->context(),
2697 length_node, elements_size_value);
2698 builder()->AddInstruction(mul);
2699 HInstruction* base = builder()->Add<HConstant>(base_size);
2700 HInstruction* total_size = HAdd::New(builder()->zone(), builder()->context(),
2701 base, mul);
2702 total_size->ClearFlag(HValue::kCanOverflow);
2703 builder()->AddInstruction(total_size);
2704 return total_size;
2705 }
2706
2707
2708 HValue* HGraphBuilder::JSArrayBuilder::EstablishEmptyArrayAllocationSize() {
2709 int base_size = JSArray::kSize;
2710 if (mode_ == TRACK_ALLOCATION_SITE) {
2711 base_size += AllocationMemento::kSize;
2712 }
2713
2714 base_size += IsFastDoubleElementsKind(kind_)
2715 ? FixedDoubleArray::SizeFor(initial_capacity())
2716 : FixedArray::SizeFor(initial_capacity());
2717
2718 return builder()->Add<HConstant>(base_size); 2689 return builder()->Add<HConstant>(base_size);
2719 } 2690 }
2720 2691
2721 2692
2722 HValue* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() { 2693 HValue* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() {
2723 HValue* size_in_bytes = EstablishEmptyArrayAllocationSize();
2724 HConstant* capacity = builder()->Add<HConstant>(initial_capacity()); 2694 HConstant* capacity = builder()->Add<HConstant>(initial_capacity());
2725 return AllocateArray(size_in_bytes, 2695 return AllocateArray(capacity,
2726 capacity,
2727 builder()->graph()->GetConstant0()); 2696 builder()->graph()->GetConstant0());
2728 } 2697 }
2729 2698
2730 2699
2731 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* capacity, 2700 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* capacity,
2732 HValue* length_field, 2701 HValue* length_field,
2733 FillMode fill_mode) { 2702 FillMode fill_mode) {
2734 HValue* size_in_bytes = EstablishAllocationSize(capacity);
2735 return AllocateArray(size_in_bytes, capacity, length_field, fill_mode);
2736 }
2737
2738
2739 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes,
2740 HValue* capacity,
2741 HValue* length_field,
2742 FillMode fill_mode) {
2743 // These HForceRepresentations are because we store these as fields in the 2703 // These HForceRepresentations are because we store these as fields in the
2744 // objects we construct, and an int32-to-smi HChange could deopt. Accept 2704 // objects we construct, and an int32-to-smi HChange could deopt. Accept
2745 // the deopt possibility now, before allocation occurs. 2705 // the deopt possibility now, before allocation occurs.
2746 capacity = 2706 capacity =
2747 builder()->AddUncasted<HForceRepresentation>(capacity, 2707 builder()->AddUncasted<HForceRepresentation>(capacity,
2748 Representation::Smi()); 2708 Representation::Smi());
2749 length_field = 2709 length_field =
2750 builder()->AddUncasted<HForceRepresentation>(length_field, 2710 builder()->AddUncasted<HForceRepresentation>(length_field,
2751 Representation::Smi()); 2711 Representation::Smi());
2712
2713 // Generate size calculation code here in order to make it dominate
2714 // the JSArray allocation.
2715 HValue* elms_size = builder()->BuildCalculateElementsSize(kind_, capacity);
2716
2752 // Allocate (dealing with failure appropriately) 2717 // Allocate (dealing with failure appropriately)
2753 HAllocate* new_object = builder()->Add<HAllocate>(size_in_bytes, 2718 HValue* array_object_size = EstablishHeaderAllocationSize();
2719 HAllocate* array_object = builder()->Add<HAllocate>(array_object_size,
2754 HType::JSArray(), NOT_TENURED, JS_ARRAY_TYPE); 2720 HType::JSArray(), NOT_TENURED, JS_ARRAY_TYPE);
2755 2721
2756 // Folded array allocation should be aligned if it has fast double elements.
2757 if (IsFastDoubleElementsKind(kind_)) {
2758 new_object->MakeDoubleAligned();
2759 }
2760
2761 // Fill in the fields: map, properties, length 2722 // Fill in the fields: map, properties, length
2762 HValue* map; 2723 HValue* map;
2763 if (allocation_site_payload_ == NULL) { 2724 if (allocation_site_payload_ == NULL) {
2764 map = EmitInternalMapCode(); 2725 map = EmitInternalMapCode();
2765 } else { 2726 } else {
2766 map = EmitMapCode(); 2727 map = EmitMapCode();
2767 } 2728 }
2768 elements_location_ = builder()->BuildJSArrayHeader(new_object,
2769 map,
2770 mode_,
2771 kind_,
2772 allocation_site_payload_,
2773 length_field);
2774 2729
2775 // Initialize the elements 2730 builder()->BuildJSArrayHeader(array_object,
2731 map,
2732 mode_,
2733 kind_,
2734 allocation_site_payload_,
2735 length_field);
2736
2737 // Allocate and initialize the elements
2738 elements_location_ =
2739 builder()->BuildAllocateElements(kind_, elms_size, NOT_TENURED);
2740
2776 builder()->BuildInitializeElementsHeader(elements_location_, kind_, capacity); 2741 builder()->BuildInitializeElementsHeader(elements_location_, kind_, capacity);
2777 2742
2743 // Set the elements
2744 builder()->Add<HStoreNamedField>(
2745 array_object, HObjectAccess::ForElementsPointer(), elements_location_);
2746
2778 if (fill_mode == FILL_WITH_HOLE) { 2747 if (fill_mode == FILL_WITH_HOLE) {
2779 builder()->BuildFillElementsWithHole(elements_location_, kind_, 2748 builder()->BuildFillElementsWithHole(elements_location_, kind_,
2780 graph()->GetConstant0(), capacity); 2749 graph()->GetConstant0(), capacity);
2781 } 2750 }
2782 2751
2783 return new_object; 2752 return array_object;
2784 } 2753 }
2785 2754
2786 2755
2787 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object, 2756 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object,
2788 Handle<Map> map) { 2757 Handle<Map> map) {
2789 return Add<HStoreNamedField>(object, HObjectAccess::ForMap(), 2758 return Add<HStoreNamedField>(object, HObjectAccess::ForMap(),
2790 Add<HConstant>(map)); 2759 Add<HConstant>(map));
2791 } 2760 }
2792 2761
2793 2762
(...skipping 7876 matching lines...) Expand 10 before | Expand all | Expand 10 after
10670 if (ShouldProduceTraceOutput()) { 10639 if (ShouldProduceTraceOutput()) {
10671 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 10640 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
10672 } 10641 }
10673 10642
10674 #ifdef DEBUG 10643 #ifdef DEBUG
10675 graph_->Verify(false); // No full verify. 10644 graph_->Verify(false); // No full verify.
10676 #endif 10645 #endif
10677 } 10646 }
10678 10647
10679 } } // namespace v8::internal 10648 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698