OLD | NEW |
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 2156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2167 elements, isolate()->factory()->fixed_array_map(), top_info()); | 2167 elements, isolate()->factory()->fixed_array_map(), top_info()); |
2168 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); | 2168 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); |
2169 } | 2169 } |
2170 } | 2170 } |
2171 } | 2171 } |
2172 return AddElementAccess(elements, checked_key, val, checked_object, | 2172 return AddElementAccess(elements, checked_key, val, checked_object, |
2173 elements_kind, is_store, load_mode); | 2173 elements_kind, is_store, load_mode); |
2174 } | 2174 } |
2175 | 2175 |
2176 | 2176 |
2177 | |
2178 HValue* HGraphBuilder::BuildAllocateArrayFromLength( | 2177 HValue* HGraphBuilder::BuildAllocateArrayFromLength( |
2179 JSArrayBuilder* array_builder, | 2178 JSArrayBuilder* array_builder, |
2180 HValue* length_argument) { | 2179 HValue* length_argument) { |
2181 if (length_argument->IsConstant() && | 2180 if (length_argument->IsConstant() && |
2182 HConstant::cast(length_argument)->HasSmiValue()) { | 2181 HConstant::cast(length_argument)->HasSmiValue()) { |
2183 int array_length = HConstant::cast(length_argument)->Integer32Value(); | 2182 int array_length = HConstant::cast(length_argument)->Integer32Value(); |
2184 HValue* new_object = array_length == 0 | 2183 if (array_length == 0) { |
2185 ? array_builder->AllocateEmptyArray() | 2184 return array_builder->AllocateEmptyArray(); |
2186 : array_builder->AllocateArray(length_argument, length_argument); | 2185 } else { |
2187 return new_object; | 2186 return array_builder->AllocateArray(length_argument, |
| 2187 array_length, |
| 2188 length_argument); |
| 2189 } |
2188 } | 2190 } |
2189 | 2191 |
2190 HValue* constant_zero = graph()->GetConstant0(); | 2192 HValue* constant_zero = graph()->GetConstant0(); |
2191 HConstant* max_alloc_length = | 2193 HConstant* max_alloc_length = |
2192 Add<HConstant>(JSObject::kInitialMaxFastElementArray); | 2194 Add<HConstant>(JSObject::kInitialMaxFastElementArray); |
2193 HInstruction* checked_length = Add<HBoundsCheck>(length_argument, | 2195 HInstruction* checked_length = Add<HBoundsCheck>(length_argument, |
2194 max_alloc_length); | 2196 max_alloc_length); |
2195 IfBuilder if_builder(this); | 2197 IfBuilder if_builder(this); |
2196 if_builder.If<HCompareNumericAndBranch>(checked_length, constant_zero, | 2198 if_builder.If<HCompareNumericAndBranch>(checked_length, constant_zero, |
2197 Token::EQ); | 2199 Token::EQ); |
2198 if_builder.Then(); | 2200 if_builder.Then(); |
2199 const int initial_capacity = JSArray::kPreallocatedArrayElements; | 2201 const int initial_capacity = JSArray::kPreallocatedArrayElements; |
2200 HConstant* initial_capacity_node = Add<HConstant>(initial_capacity); | 2202 HConstant* initial_capacity_node = Add<HConstant>(initial_capacity); |
2201 Push(initial_capacity_node); // capacity | 2203 Push(initial_capacity_node); // capacity |
2202 Push(constant_zero); // length | 2204 Push(constant_zero); // length |
2203 if_builder.Else(); | 2205 if_builder.Else(); |
2204 if (!(top_info()->IsStub()) && | 2206 if (!(top_info()->IsStub()) && |
2205 IsFastPackedElementsKind(array_builder->kind())) { | 2207 IsFastPackedElementsKind(array_builder->kind())) { |
2206 // We'll come back later with better (holey) feedback. | 2208 // We'll come back later with better (holey) feedback. |
2207 if_builder.Deopt("Holey array despite packed elements_kind feedback"); | 2209 if_builder.Deopt("Holey array despite packed elements_kind feedback"); |
2208 } else { | 2210 } else { |
2209 Push(checked_length); // capacity | 2211 Push(checked_length); // capacity |
2210 Push(checked_length); // length | 2212 Push(checked_length); // length |
2211 } | 2213 } |
2212 if_builder.End(); | 2214 if_builder.End(); |
2213 | 2215 |
2214 // Figure out total size | 2216 // Figure out total size |
2215 HValue* length = Pop(); | 2217 HValue* length = Pop(); |
2216 HValue* capacity = Pop(); | 2218 HValue* capacity = Pop(); |
2217 return array_builder->AllocateArray(capacity, length); | 2219 return array_builder->AllocateArray(capacity, max_alloc_length, length); |
2218 } | 2220 } |
2219 | 2221 |
2220 HValue* HGraphBuilder::BuildAllocateElements(ElementsKind kind, | 2222 HValue* HGraphBuilder::BuildCalculateElementsSize(ElementsKind kind, |
2221 HValue* capacity) { | 2223 HValue* capacity) { |
2222 int elements_size; | 2224 int elements_size = IsFastDoubleElementsKind(kind) |
2223 InstanceType instance_type; | 2225 ? kDoubleSize |
2224 | 2226 : kPointerSize; |
2225 if (IsFastDoubleElementsKind(kind)) { | |
2226 elements_size = kDoubleSize; | |
2227 instance_type = FIXED_DOUBLE_ARRAY_TYPE; | |
2228 } else { | |
2229 elements_size = kPointerSize; | |
2230 instance_type = FIXED_ARRAY_TYPE; | |
2231 } | |
2232 | 2227 |
2233 HConstant* elements_size_value = Add<HConstant>(elements_size); | 2228 HConstant* elements_size_value = Add<HConstant>(elements_size); |
2234 HValue* mul = AddUncasted<HMul>(capacity, elements_size_value); | 2229 HInstruction* mul = HMul::NewImul(zone(), context(), |
| 2230 capacity->ActualValue(), |
| 2231 elements_size_value); |
| 2232 AddInstruction(mul); |
2235 mul->ClearFlag(HValue::kCanOverflow); | 2233 mul->ClearFlag(HValue::kCanOverflow); |
2236 | 2234 |
| 2235 STATIC_ASSERT(FixedDoubleArray::kHeaderSize == FixedArray::kHeaderSize); |
| 2236 |
2237 HConstant* header_size = Add<HConstant>(FixedArray::kHeaderSize); | 2237 HConstant* header_size = Add<HConstant>(FixedArray::kHeaderSize); |
2238 HValue* total_size = AddUncasted<HAdd>(mul, header_size); | 2238 HValue* total_size = AddUncasted<HAdd>(mul, header_size); |
2239 total_size->ClearFlag(HValue::kCanOverflow); | 2239 total_size->ClearFlag(HValue::kCanOverflow); |
2240 | 2240 return total_size; |
2241 return Add<HAllocate>(total_size, HType::JSArray(), | |
2242 isolate()->heap()->GetPretenureMode(), instance_type); | |
2243 } | 2241 } |
2244 | 2242 |
2245 | 2243 |
| 2244 HConstant* HGraphBuilder::EstablishHeaderAllocationSize( |
| 2245 AllocationSiteMode mode) { |
| 2246 int base_size = JSArray::kSize; |
| 2247 if (mode == TRACK_ALLOCATION_SITE) { |
| 2248 base_size += AllocationMemento::kSize; |
| 2249 } |
| 2250 return Add<HConstant>(base_size); |
| 2251 } |
| 2252 |
| 2253 |
| 2254 HConstant* HGraphBuilder::EstablishElementsAllocationSize( |
| 2255 ElementsKind kind, |
| 2256 int capacity) { |
| 2257 int base_size = IsFastDoubleElementsKind(kind) |
| 2258 ? FixedDoubleArray::SizeFor(capacity) |
| 2259 : FixedArray::SizeFor(capacity); |
| 2260 |
| 2261 return Add<HConstant>(base_size); |
| 2262 } |
| 2263 |
| 2264 |
| 2265 HAllocate* HGraphBuilder::BuildAllocateElements(ElementsKind kind, |
| 2266 HValue* size_in_bytes, |
| 2267 PretenureFlag pretenure) { |
| 2268 InstanceType instance_type = IsFastDoubleElementsKind(kind) |
| 2269 ? FIXED_DOUBLE_ARRAY_TYPE |
| 2270 : FIXED_ARRAY_TYPE; |
| 2271 |
| 2272 return Add<HAllocate>(size_in_bytes, HType::JSArray(), |
| 2273 pretenure, instance_type); |
| 2274 } |
| 2275 |
| 2276 |
2246 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements, | 2277 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements, |
2247 ElementsKind kind, | 2278 ElementsKind kind, |
2248 HValue* capacity) { | 2279 HValue* capacity) { |
2249 Factory* factory = isolate()->factory(); | 2280 Factory* factory = isolate()->factory(); |
2250 Handle<Map> map = IsFastDoubleElementsKind(kind) | 2281 Handle<Map> map = IsFastDoubleElementsKind(kind) |
2251 ? factory->fixed_double_array_map() | 2282 ? factory->fixed_double_array_map() |
2252 : factory->fixed_array_map(); | 2283 : factory->fixed_array_map(); |
2253 | 2284 |
2254 AddStoreMapConstant(elements, map); | 2285 AddStoreMapConstant(elements, map); |
2255 Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(), | 2286 Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(), |
2256 capacity); | 2287 capacity); |
2257 } | 2288 } |
2258 | 2289 |
2259 | 2290 |
2260 HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader( | 2291 HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader( |
2261 ElementsKind kind, | 2292 ElementsKind kind, |
2262 HValue* capacity) { | 2293 HValue* capacity) { |
2263 // The HForceRepresentation is to prevent possible deopt on int-smi | 2294 // The HForceRepresentation is to prevent possible deopt on int-smi |
2264 // conversion after allocation but before the new object fields are set. | 2295 // conversion after allocation but before the new object fields are set. |
2265 capacity = AddUncasted<HForceRepresentation>(capacity, Representation::Smi()); | 2296 capacity = AddUncasted<HForceRepresentation>(capacity, Representation::Smi()); |
2266 HValue* new_elements = BuildAllocateElements(kind, capacity); | 2297 HValue* size_in_bytes = BuildCalculateElementsSize(kind, capacity); |
| 2298 HValue* new_elements = BuildAllocateElements( |
| 2299 kind, size_in_bytes, isolate()->heap()->GetPretenureMode()); |
2267 BuildInitializeElementsHeader(new_elements, kind, capacity); | 2300 BuildInitializeElementsHeader(new_elements, kind, capacity); |
2268 return new_elements; | 2301 return new_elements; |
2269 } | 2302 } |
2270 | 2303 |
2271 | 2304 |
2272 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array, | 2305 void HGraphBuilder::BuildJSArrayHeader(HValue* array, |
2273 HValue* array_map, | 2306 HValue* array_map, |
2274 AllocationSiteMode mode, | 2307 AllocationSiteMode mode, |
2275 ElementsKind elements_kind, | 2308 ElementsKind elements_kind, |
2276 HValue* allocation_site_payload, | 2309 HValue* allocation_site_payload, |
2277 HValue* length_field) { | 2310 HValue* length_field) { |
2278 | |
2279 Add<HStoreNamedField>(array, HObjectAccess::ForMap(), array_map); | 2311 Add<HStoreNamedField>(array, HObjectAccess::ForMap(), array_map); |
2280 | 2312 |
2281 HConstant* empty_fixed_array = | 2313 HConstant* empty_fixed_array = |
2282 Add<HConstant>(isolate()->factory()->empty_fixed_array()); | 2314 Add<HConstant>(isolate()->factory()->empty_fixed_array()); |
2283 | 2315 |
2284 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); | 2316 Add<HStoreNamedField>( |
2285 Add<HStoreNamedField>(array, access, empty_fixed_array); | 2317 array, HObjectAccess::ForPropertiesPointer(), empty_fixed_array); |
2286 Add<HStoreNamedField>(array, HObjectAccess::ForArrayLength(elements_kind), | 2318 |
2287 length_field); | 2319 Add<HStoreNamedField>( |
| 2320 array, HObjectAccess::ForElementsPointer(), empty_fixed_array); |
| 2321 |
| 2322 Add<HStoreNamedField>( |
| 2323 array, HObjectAccess::ForArrayLength(elements_kind), length_field); |
2288 | 2324 |
2289 if (mode == TRACK_ALLOCATION_SITE) { | 2325 if (mode == TRACK_ALLOCATION_SITE) { |
2290 BuildCreateAllocationMemento( | 2326 BuildCreateAllocationMemento( |
2291 array, Add<HConstant>(JSArray::kSize), allocation_site_payload); | 2327 array, Add<HConstant>(JSArray::kSize), allocation_site_payload); |
2292 } | 2328 } |
2293 | |
2294 int elements_location = JSArray::kSize; | |
2295 if (mode == TRACK_ALLOCATION_SITE) { | |
2296 elements_location += AllocationMemento::kSize; | |
2297 } | |
2298 | |
2299 HInnerAllocatedObject* elements = Add<HInnerAllocatedObject>( | |
2300 array, Add<HConstant>(elements_location)); | |
2301 Add<HStoreNamedField>(array, HObjectAccess::ForElementsPointer(), elements); | |
2302 return elements; | |
2303 } | 2329 } |
2304 | 2330 |
2305 | 2331 |
2306 HInstruction* HGraphBuilder::AddElementAccess( | 2332 HInstruction* HGraphBuilder::AddElementAccess( |
2307 HValue* elements, | 2333 HValue* elements, |
2308 HValue* checked_key, | 2334 HValue* checked_key, |
2309 HValue* val, | 2335 HValue* val, |
2310 HValue* dependency, | 2336 HValue* dependency, |
2311 ElementsKind elements_kind, | 2337 ElementsKind elements_kind, |
2312 bool is_store, | 2338 bool is_store, |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2503 | 2529 |
2504 | 2530 |
2505 HValue* HGraphBuilder::BuildCloneShallowArray(HValue* boilerplate, | 2531 HValue* HGraphBuilder::BuildCloneShallowArray(HValue* boilerplate, |
2506 HValue* allocation_site, | 2532 HValue* allocation_site, |
2507 AllocationSiteMode mode, | 2533 AllocationSiteMode mode, |
2508 ElementsKind kind, | 2534 ElementsKind kind, |
2509 int length) { | 2535 int length) { |
2510 NoObservableSideEffectsScope no_effects(this); | 2536 NoObservableSideEffectsScope no_effects(this); |
2511 | 2537 |
2512 // All sizes here are multiples of kPointerSize. | 2538 // All sizes here are multiples of kPointerSize. |
2513 int size = JSArray::kSize; | 2539 HConstant* size_in_bytes = EstablishHeaderAllocationSize(mode); |
2514 if (mode == TRACK_ALLOCATION_SITE) { | |
2515 size += AllocationMemento::kSize; | |
2516 } | |
2517 | |
2518 HValue* size_in_bytes = Add<HConstant>(size); | |
2519 HInstruction* object = Add<HAllocate>(size_in_bytes, | 2540 HInstruction* object = Add<HAllocate>(size_in_bytes, |
2520 HType::JSObject(), | 2541 HType::JSObject(), |
2521 NOT_TENURED, | 2542 NOT_TENURED, |
2522 JS_OBJECT_TYPE); | 2543 JS_OBJECT_TYPE); |
2523 | 2544 |
2524 // Copy the JS array part. | 2545 // Copy the JS array part. |
2525 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { | 2546 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { |
2526 if ((i != JSArray::kElementsOffset) || (length == 0)) { | 2547 if ((i != JSArray::kElementsOffset) || (length == 0)) { |
2527 HObjectAccess access = HObjectAccess::ForJSArrayOffset(i); | 2548 HObjectAccess access = HObjectAccess::ForJSArrayOffset(i); |
2528 Add<HStoreNamedField>(object, access, | 2549 Add<HStoreNamedField>(object, access, |
2529 Add<HLoadNamedField>(boilerplate, access)); | 2550 Add<HLoadNamedField>(boilerplate, access)); |
2530 } | 2551 } |
2531 } | 2552 } |
2532 | 2553 |
2533 // Create an allocation site info if requested. | 2554 // Create an allocation site info if requested. |
2534 if (mode == TRACK_ALLOCATION_SITE) { | 2555 if (mode == TRACK_ALLOCATION_SITE) { |
2535 BuildCreateAllocationMemento( | 2556 BuildCreateAllocationMemento( |
2536 object, Add<HConstant>(JSArray::kSize), allocation_site); | 2557 object, Add<HConstant>(JSArray::kSize), allocation_site); |
2537 } | 2558 } |
2538 | 2559 |
2539 if (length > 0) { | 2560 if (length > 0) { |
2540 HValue* boilerplate_elements = AddLoadElements(boilerplate); | 2561 HValue* boilerplate_elements = AddLoadElements(boilerplate); |
2541 HValue* object_elements; | 2562 HConstant* elements_size = EstablishElementsAllocationSize(kind, length); |
2542 if (IsFastDoubleElementsKind(kind)) { | 2563 HValue* object_elements = |
2543 HValue* elems_size = Add<HConstant>(FixedDoubleArray::SizeFor(length)); | 2564 BuildAllocateElements(kind, elements_size, NOT_TENURED); |
2544 object_elements = Add<HAllocate>(elems_size, HType::JSArray(), | 2565 |
2545 NOT_TENURED, FIXED_DOUBLE_ARRAY_TYPE); | |
2546 } else { | |
2547 HValue* elems_size = Add<HConstant>(FixedArray::SizeFor(length)); | |
2548 object_elements = Add<HAllocate>(elems_size, HType::JSArray(), | |
2549 NOT_TENURED, FIXED_ARRAY_TYPE); | |
2550 } | |
2551 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), | 2566 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), |
2552 object_elements); | 2567 object_elements); |
2553 | 2568 |
2554 // Copy the elements array header. | 2569 // Copy the elements array header. |
2555 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { | 2570 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { |
2556 HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i); | 2571 HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i); |
2557 Add<HStoreNamedField>(object_elements, access, | 2572 Add<HStoreNamedField>(object_elements, access, |
2558 Add<HLoadNamedField>(boilerplate_elements, access)); | 2573 Add<HLoadNamedField>(boilerplate_elements, access)); |
2559 } | 2574 } |
2560 | 2575 |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2747 } | 2762 } |
2748 | 2763 |
2749 | 2764 |
2750 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { | 2765 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { |
2751 // Find the map near the constructor function | 2766 // Find the map near the constructor function |
2752 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); | 2767 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); |
2753 return builder()->AddLoadNamedField(constructor_function_, access); | 2768 return builder()->AddLoadNamedField(constructor_function_, access); |
2754 } | 2769 } |
2755 | 2770 |
2756 | 2771 |
2757 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( | 2772 HAllocate* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() { |
2758 HValue* length_node) { | |
2759 ASSERT(length_node != NULL); | |
2760 | |
2761 int base_size = JSArray::kSize; | |
2762 if (mode_ == TRACK_ALLOCATION_SITE) { | |
2763 base_size += AllocationMemento::kSize; | |
2764 } | |
2765 | |
2766 STATIC_ASSERT(FixedDoubleArray::kHeaderSize == FixedArray::kHeaderSize); | |
2767 base_size += FixedArray::kHeaderSize; | |
2768 | |
2769 HInstruction* elements_size_value = | |
2770 builder()->Add<HConstant>(elements_size()); | |
2771 HInstruction* mul = HMul::NewImul(builder()->zone(), builder()->context(), | |
2772 length_node, elements_size_value); | |
2773 builder()->AddInstruction(mul); | |
2774 HInstruction* base = builder()->Add<HConstant>(base_size); | |
2775 HInstruction* total_size = HAdd::New(builder()->zone(), builder()->context(), | |
2776 base, mul); | |
2777 total_size->ClearFlag(HValue::kCanOverflow); | |
2778 builder()->AddInstruction(total_size); | |
2779 return total_size; | |
2780 } | |
2781 | |
2782 | |
2783 HValue* HGraphBuilder::JSArrayBuilder::EstablishEmptyArrayAllocationSize() { | |
2784 int base_size = JSArray::kSize; | |
2785 if (mode_ == TRACK_ALLOCATION_SITE) { | |
2786 base_size += AllocationMemento::kSize; | |
2787 } | |
2788 | |
2789 base_size += IsFastDoubleElementsKind(kind_) | |
2790 ? FixedDoubleArray::SizeFor(initial_capacity()) | |
2791 : FixedArray::SizeFor(initial_capacity()); | |
2792 | |
2793 return builder()->Add<HConstant>(base_size); | |
2794 } | |
2795 | |
2796 | |
2797 HValue* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() { | |
2798 HValue* size_in_bytes = EstablishEmptyArrayAllocationSize(); | |
2799 HConstant* capacity = builder()->Add<HConstant>(initial_capacity()); | 2773 HConstant* capacity = builder()->Add<HConstant>(initial_capacity()); |
2800 return AllocateArray(size_in_bytes, | 2774 return AllocateArray(capacity, |
2801 capacity, | |
2802 builder()->graph()->GetConstant0()); | 2775 builder()->graph()->GetConstant0()); |
2803 } | 2776 } |
2804 | 2777 |
2805 | 2778 |
2806 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* capacity, | 2779 HAllocate* HGraphBuilder::JSArrayBuilder::AllocateArray( |
2807 HValue* length_field, | 2780 HValue* capacity, |
2808 FillMode fill_mode) { | 2781 HConstant* capacity_upper_bound, |
2809 HValue* size_in_bytes = EstablishAllocationSize(capacity); | 2782 HValue* length_field, |
2810 return AllocateArray(size_in_bytes, capacity, length_field, fill_mode); | 2783 FillMode fill_mode) { |
| 2784 return AllocateArray(capacity, |
| 2785 capacity_upper_bound->GetInteger32Constant(), |
| 2786 length_field, |
| 2787 fill_mode); |
2811 } | 2788 } |
2812 | 2789 |
2813 | 2790 |
2814 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes, | 2791 HAllocate* HGraphBuilder::JSArrayBuilder::AllocateArray( |
2815 HValue* capacity, | 2792 HValue* capacity, |
2816 HValue* length_field, | 2793 int capacity_upper_bound, |
2817 FillMode fill_mode) { | 2794 HValue* length_field, |
| 2795 FillMode fill_mode) { |
| 2796 HConstant* elememts_size_upper_bound = capacity->IsInteger32Constant() |
| 2797 ? HConstant::cast(capacity) |
| 2798 : builder()->EstablishElementsAllocationSize(kind_, capacity_upper_bound); |
| 2799 |
| 2800 HAllocate* array = AllocateArray(capacity, length_field, fill_mode); |
| 2801 if (!capacity->IsInteger32Constant()) { |
| 2802 // For constant sizes the size upper bound is set automatically. |
| 2803 elements_location_->set_size_upper_bound(elememts_size_upper_bound); |
| 2804 } |
| 2805 return array; |
| 2806 } |
| 2807 |
| 2808 |
| 2809 HAllocate* HGraphBuilder::JSArrayBuilder::AllocateArray( |
| 2810 HValue* capacity, |
| 2811 HValue* length_field, |
| 2812 FillMode fill_mode) { |
2818 // These HForceRepresentations are because we store these as fields in the | 2813 // These HForceRepresentations are because we store these as fields in the |
2819 // objects we construct, and an int32-to-smi HChange could deopt. Accept | 2814 // objects we construct, and an int32-to-smi HChange could deopt. Accept |
2820 // the deopt possibility now, before allocation occurs. | 2815 // the deopt possibility now, before allocation occurs. |
2821 capacity = | 2816 capacity = |
2822 builder()->AddUncasted<HForceRepresentation>(capacity, | 2817 builder()->AddUncasted<HForceRepresentation>(capacity, |
2823 Representation::Smi()); | 2818 Representation::Smi()); |
2824 length_field = | 2819 length_field = |
2825 builder()->AddUncasted<HForceRepresentation>(length_field, | 2820 builder()->AddUncasted<HForceRepresentation>(length_field, |
2826 Representation::Smi()); | 2821 Representation::Smi()); |
| 2822 |
| 2823 // Generate size calculation code here in order to make it dominate |
| 2824 // the JSArray allocation. |
| 2825 HValue* elements_size = |
| 2826 builder()->BuildCalculateElementsSize(kind_, capacity); |
| 2827 |
2827 // Allocate (dealing with failure appropriately) | 2828 // Allocate (dealing with failure appropriately) |
2828 HAllocate* new_object = builder()->Add<HAllocate>(size_in_bytes, | 2829 HConstant* array_object_size = |
| 2830 builder()->EstablishHeaderAllocationSize(mode_); |
| 2831 HAllocate* array_object = builder()->Add<HAllocate>(array_object_size, |
2829 HType::JSArray(), NOT_TENURED, JS_ARRAY_TYPE); | 2832 HType::JSArray(), NOT_TENURED, JS_ARRAY_TYPE); |
2830 | 2833 |
2831 // Folded array allocation should be aligned if it has fast double elements. | |
2832 if (IsFastDoubleElementsKind(kind_)) { | |
2833 new_object->MakeDoubleAligned(); | |
2834 } | |
2835 | |
2836 // Fill in the fields: map, properties, length | 2834 // Fill in the fields: map, properties, length |
2837 HValue* map; | 2835 HValue* map; |
2838 if (allocation_site_payload_ == NULL) { | 2836 if (allocation_site_payload_ == NULL) { |
2839 map = EmitInternalMapCode(); | 2837 map = EmitInternalMapCode(); |
2840 } else { | 2838 } else { |
2841 map = EmitMapCode(); | 2839 map = EmitMapCode(); |
2842 } | 2840 } |
2843 elements_location_ = builder()->BuildJSArrayHeader(new_object, | |
2844 map, | |
2845 mode_, | |
2846 kind_, | |
2847 allocation_site_payload_, | |
2848 length_field); | |
2849 | 2841 |
2850 // Initialize the elements | 2842 builder()->BuildJSArrayHeader(array_object, |
| 2843 map, |
| 2844 mode_, |
| 2845 kind_, |
| 2846 allocation_site_payload_, |
| 2847 length_field); |
| 2848 |
| 2849 // Allocate and initialize the elements |
| 2850 elements_location_ = |
| 2851 builder()->BuildAllocateElements(kind_, elements_size, NOT_TENURED); |
| 2852 |
2851 builder()->BuildInitializeElementsHeader(elements_location_, kind_, capacity); | 2853 builder()->BuildInitializeElementsHeader(elements_location_, kind_, capacity); |
2852 | 2854 |
| 2855 // Set the elements |
| 2856 builder()->Add<HStoreNamedField>( |
| 2857 array_object, HObjectAccess::ForElementsPointer(), elements_location_); |
| 2858 |
2853 if (fill_mode == FILL_WITH_HOLE) { | 2859 if (fill_mode == FILL_WITH_HOLE) { |
2854 builder()->BuildFillElementsWithHole(elements_location_, kind_, | 2860 builder()->BuildFillElementsWithHole(elements_location_, kind_, |
2855 graph()->GetConstant0(), capacity); | 2861 graph()->GetConstant0(), capacity); |
2856 } | 2862 } |
2857 | 2863 |
2858 return new_object; | 2864 return array_object; |
2859 } | 2865 } |
2860 | 2866 |
2861 | 2867 |
2862 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object, | 2868 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object, |
2863 Handle<Map> map) { | 2869 Handle<Map> map) { |
2864 return Add<HStoreNamedField>(object, HObjectAccess::ForMap(), | 2870 return Add<HStoreNamedField>(object, HObjectAccess::ForMap(), |
2865 Add<HConstant>(map)); | 2871 Add<HConstant>(map)); |
2866 } | 2872 } |
2867 | 2873 |
2868 | 2874 |
(...skipping 8126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10995 if (ShouldProduceTraceOutput()) { | 11001 if (ShouldProduceTraceOutput()) { |
10996 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 11002 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
10997 } | 11003 } |
10998 | 11004 |
10999 #ifdef DEBUG | 11005 #ifdef DEBUG |
11000 graph_->Verify(false); // No full verify. | 11006 graph_->Verify(false); // No full verify. |
11001 #endif | 11007 #endif |
11002 } | 11008 } |
11003 | 11009 |
11004 } } // namespace v8::internal | 11010 } } // namespace v8::internal |
OLD | NEW |