Chromium Code Reviews| 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 2114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2125 elements, isolate()->factory()->fixed_array_map(), top_info()); | 2125 elements, isolate()->factory()->fixed_array_map(), top_info()); |
| 2126 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); | 2126 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); |
| 2127 } | 2127 } |
| 2128 } | 2128 } |
| 2129 } | 2129 } |
| 2130 return AddElementAccess(elements, checked_key, val, checked_object, | 2130 return AddElementAccess(elements, checked_key, val, checked_object, |
| 2131 elements_kind, is_store, load_mode); | 2131 elements_kind, is_store, load_mode); |
| 2132 } | 2132 } |
| 2133 | 2133 |
| 2134 | 2134 |
| 2135 | |
| 2136 HValue* HGraphBuilder::BuildAllocateArrayFromLength( | 2135 HValue* HGraphBuilder::BuildAllocateArrayFromLength( |
| 2137 JSArrayBuilder* array_builder, | 2136 JSArrayBuilder* array_builder, |
| 2138 HValue* length_argument) { | 2137 HValue* length_argument) { |
| 2139 if (length_argument->IsConstant() && | 2138 if (length_argument->IsConstant() && |
| 2140 HConstant::cast(length_argument)->HasSmiValue()) { | 2139 HConstant::cast(length_argument)->HasSmiValue()) { |
| 2141 int array_length = HConstant::cast(length_argument)->Integer32Value(); | 2140 int array_length = HConstant::cast(length_argument)->Integer32Value(); |
| 2142 HValue* new_object = array_length == 0 | 2141 if (array_length == 0) { |
| 2143 ? array_builder->AllocateEmptyArray() | 2142 return array_builder->AllocateEmptyArray(); |
| 2144 : array_builder->AllocateArray(length_argument, length_argument); | 2143 } else { |
| 2145 return new_object; | 2144 return array_builder->AllocateArray(length_argument, |
| 2145 array_length, | |
| 2146 length_argument); | |
| 2147 } | |
| 2146 } | 2148 } |
| 2147 | 2149 |
| 2148 HValue* constant_zero = graph()->GetConstant0(); | 2150 HValue* constant_zero = graph()->GetConstant0(); |
| 2149 HConstant* max_alloc_length = | 2151 HConstant* max_alloc_length = |
| 2150 Add<HConstant>(JSObject::kInitialMaxFastElementArray); | 2152 Add<HConstant>(JSObject::kInitialMaxFastElementArray); |
| 2151 HInstruction* checked_length = Add<HBoundsCheck>(length_argument, | 2153 HInstruction* checked_length = Add<HBoundsCheck>(length_argument, |
| 2152 max_alloc_length); | 2154 max_alloc_length); |
| 2153 IfBuilder if_builder(this); | 2155 IfBuilder if_builder(this); |
| 2154 if_builder.If<HCompareNumericAndBranch>(checked_length, constant_zero, | 2156 if_builder.If<HCompareNumericAndBranch>(checked_length, constant_zero, |
| 2155 Token::EQ); | 2157 Token::EQ); |
| 2156 if_builder.Then(); | 2158 if_builder.Then(); |
| 2157 const int initial_capacity = JSArray::kPreallocatedArrayElements; | 2159 const int initial_capacity = JSArray::kPreallocatedArrayElements; |
| 2158 HConstant* initial_capacity_node = Add<HConstant>(initial_capacity); | 2160 HConstant* initial_capacity_node = Add<HConstant>(initial_capacity); |
| 2159 Push(initial_capacity_node); // capacity | 2161 Push(initial_capacity_node); // capacity |
| 2160 Push(constant_zero); // length | 2162 Push(constant_zero); // length |
| 2161 if_builder.Else(); | 2163 if_builder.Else(); |
| 2162 if (!(top_info()->IsStub()) && | 2164 if (!(top_info()->IsStub()) && |
| 2163 IsFastPackedElementsKind(array_builder->kind())) { | 2165 IsFastPackedElementsKind(array_builder->kind())) { |
| 2164 // We'll come back later with better (holey) feedback. | 2166 // We'll come back later with better (holey) feedback. |
| 2165 if_builder.Deopt("Holey array despite packed elements_kind feedback"); | 2167 if_builder.Deopt("Holey array despite packed elements_kind feedback"); |
| 2166 } else { | 2168 } else { |
| 2167 Push(checked_length); // capacity | 2169 Push(checked_length); // capacity |
| 2168 Push(checked_length); // length | 2170 Push(checked_length); // length |
| 2169 } | 2171 } |
| 2170 if_builder.End(); | 2172 if_builder.End(); |
| 2171 | 2173 |
| 2172 // Figure out total size | 2174 // Figure out total size |
| 2173 HValue* length = Pop(); | 2175 HValue* length = Pop(); |
| 2174 HValue* capacity = Pop(); | 2176 HValue* capacity = Pop(); |
| 2175 return array_builder->AllocateArray(capacity, length); | 2177 return array_builder->AllocateArray(capacity, max_alloc_length, length); |
| 2176 } | 2178 } |
| 2177 | 2179 |
| 2178 HValue* HGraphBuilder::BuildAllocateElements(ElementsKind kind, | 2180 HValue* HGraphBuilder::BuildCalculateElementsSize(ElementsKind kind, |
| 2179 HValue* capacity) { | 2181 HValue* capacity) { |
| 2180 int elements_size; | 2182 int elements_size = IsFastDoubleElementsKind(kind) |
| 2181 InstanceType instance_type; | 2183 ? kDoubleSize |
| 2182 | 2184 : kPointerSize; |
| 2183 if (IsFastDoubleElementsKind(kind)) { | |
| 2184 elements_size = kDoubleSize; | |
| 2185 instance_type = FIXED_DOUBLE_ARRAY_TYPE; | |
| 2186 } else { | |
| 2187 elements_size = kPointerSize; | |
| 2188 instance_type = FIXED_ARRAY_TYPE; | |
| 2189 } | |
| 2190 | 2185 |
| 2191 HConstant* elements_size_value = Add<HConstant>(elements_size); | 2186 HConstant* elements_size_value = Add<HConstant>(elements_size); |
| 2192 HValue* mul = AddUncasted<HMul>(capacity, elements_size_value); | 2187 HInstruction* mul = HMul::NewImul(zone(), context(), |
| 2188 capacity->ActualValue(), | |
| 2189 elements_size_value); | |
| 2190 AddInstruction(mul); | |
| 2193 mul->ClearFlag(HValue::kCanOverflow); | 2191 mul->ClearFlag(HValue::kCanOverflow); |
| 2194 | 2192 |
| 2193 STATIC_ASSERT(FixedDoubleArray::kHeaderSize == FixedArray::kHeaderSize); | |
| 2194 | |
| 2195 HConstant* header_size = Add<HConstant>(FixedArray::kHeaderSize); | 2195 HConstant* header_size = Add<HConstant>(FixedArray::kHeaderSize); |
| 2196 HValue* total_size = AddUncasted<HAdd>(mul, header_size); | 2196 HValue* total_size = AddUncasted<HAdd>(mul, header_size); |
| 2197 total_size->ClearFlag(HValue::kCanOverflow); | 2197 total_size->ClearFlag(HValue::kCanOverflow); |
| 2198 | 2198 return total_size; |
| 2199 return Add<HAllocate>(total_size, HType::JSArray(), | |
| 2200 isolate()->heap()->GetPretenureMode(), instance_type); | |
| 2201 } | 2199 } |
| 2202 | 2200 |
| 2203 | 2201 |
| 2202 HConstant* HGraphBuilder::EstablishHeaderAllocationSize( | |
| 2203 AllocationSiteMode mode) { | |
| 2204 int base_size = JSArray::kSize; | |
| 2205 if (mode == TRACK_ALLOCATION_SITE) { | |
| 2206 base_size += AllocationMemento::kSize; | |
| 2207 } | |
| 2208 return Add<HConstant>(base_size); | |
| 2209 } | |
| 2210 | |
| 2211 | |
| 2212 HConstant* HGraphBuilder::EstablishElementsAllocationSize( | |
| 2213 ElementsKind kind, | |
| 2214 int capacity) { | |
| 2215 int base_size = IsFastDoubleElementsKind(kind) | |
| 2216 ? FixedDoubleArray::SizeFor(capacity) | |
| 2217 : FixedArray::SizeFor(capacity); | |
| 2218 | |
| 2219 return Add<HConstant>(base_size); | |
| 2220 } | |
| 2221 | |
| 2222 | |
| 2223 HAllocate* HGraphBuilder::BuildAllocateElements(ElementsKind kind, | |
| 2224 HValue* size_in_bytes, | |
| 2225 PretenureFlag pretenure) { | |
| 2226 InstanceType instance_type = IsFastDoubleElementsKind(kind) | |
| 2227 ? FIXED_DOUBLE_ARRAY_TYPE | |
| 2228 : FIXED_ARRAY_TYPE; | |
| 2229 | |
| 2230 return Add<HAllocate>(size_in_bytes, HType::JSArray(), | |
| 2231 pretenure, instance_type); | |
| 2232 } | |
| 2233 | |
| 2234 | |
| 2204 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements, | 2235 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements, |
| 2205 ElementsKind kind, | 2236 ElementsKind kind, |
| 2206 HValue* capacity) { | 2237 HValue* capacity) { |
| 2207 Factory* factory = isolate()->factory(); | 2238 Factory* factory = isolate()->factory(); |
| 2208 Handle<Map> map = IsFastDoubleElementsKind(kind) | 2239 Handle<Map> map = IsFastDoubleElementsKind(kind) |
| 2209 ? factory->fixed_double_array_map() | 2240 ? factory->fixed_double_array_map() |
| 2210 : factory->fixed_array_map(); | 2241 : factory->fixed_array_map(); |
| 2211 | 2242 |
| 2212 AddStoreMapConstant(elements, map); | 2243 AddStoreMapConstant(elements, map); |
| 2213 Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(), | 2244 Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(), |
| 2214 capacity); | 2245 capacity); |
| 2215 } | 2246 } |
| 2216 | 2247 |
| 2217 | 2248 |
| 2218 HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader( | 2249 HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader( |
| 2219 ElementsKind kind, | 2250 ElementsKind kind, |
| 2220 HValue* capacity) { | 2251 HValue* capacity) { |
| 2221 // The HForceRepresentation is to prevent possible deopt on int-smi | 2252 // The HForceRepresentation is to prevent possible deopt on int-smi |
| 2222 // conversion after allocation but before the new object fields are set. | 2253 // conversion after allocation but before the new object fields are set. |
| 2223 capacity = AddUncasted<HForceRepresentation>(capacity, Representation::Smi()); | 2254 capacity = AddUncasted<HForceRepresentation>(capacity, Representation::Smi()); |
| 2224 HValue* new_elements = BuildAllocateElements(kind, capacity); | 2255 HValue* size_in_bytes = BuildCalculateElementsSize(kind, capacity); |
| 2256 HValue* new_elements = BuildAllocateElements( | |
| 2257 kind, size_in_bytes, isolate()->heap()->GetPretenureMode()); | |
| 2225 BuildInitializeElementsHeader(new_elements, kind, capacity); | 2258 BuildInitializeElementsHeader(new_elements, kind, capacity); |
| 2226 return new_elements; | 2259 return new_elements; |
| 2227 } | 2260 } |
| 2228 | 2261 |
| 2229 | 2262 |
| 2230 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array, | 2263 void HGraphBuilder::BuildJSArrayHeader(HValue* array, |
| 2231 HValue* array_map, | 2264 HValue* array_map, |
| 2232 AllocationSiteMode mode, | 2265 AllocationSiteMode mode, |
| 2233 ElementsKind elements_kind, | 2266 ElementsKind elements_kind, |
| 2234 HValue* allocation_site_payload, | 2267 HValue* allocation_site_payload, |
| 2235 HValue* length_field) { | 2268 HValue* length_field) { |
| 2236 | |
| 2237 Add<HStoreNamedField>(array, HObjectAccess::ForMap(), array_map); | 2269 Add<HStoreNamedField>(array, HObjectAccess::ForMap(), array_map); |
| 2238 | 2270 |
| 2239 HConstant* empty_fixed_array = | 2271 HConstant* empty_fixed_array = |
| 2240 Add<HConstant>(isolate()->factory()->empty_fixed_array()); | 2272 Add<HConstant>(isolate()->factory()->empty_fixed_array()); |
| 2241 | 2273 |
| 2242 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); | 2274 Add<HStoreNamedField>( |
| 2243 Add<HStoreNamedField>(array, access, empty_fixed_array); | 2275 array, HObjectAccess::ForPropertiesPointer(), empty_fixed_array); |
| 2244 Add<HStoreNamedField>(array, HObjectAccess::ForArrayLength(elements_kind), | 2276 |
| 2245 length_field); | 2277 Add<HStoreNamedField>( |
| 2278 array, HObjectAccess::ForElementsPointer(), empty_fixed_array); | |
| 2279 | |
| 2280 Add<HStoreNamedField>( | |
| 2281 array, HObjectAccess::ForArrayLength(elements_kind), length_field); | |
| 2246 | 2282 |
| 2247 if (mode == TRACK_ALLOCATION_SITE) { | 2283 if (mode == TRACK_ALLOCATION_SITE) { |
| 2248 BuildCreateAllocationMemento( | 2284 BuildCreateAllocationMemento( |
| 2249 array, Add<HConstant>(JSArray::kSize), allocation_site_payload); | 2285 array, Add<HConstant>(JSArray::kSize), allocation_site_payload); |
| 2250 } | 2286 } |
| 2251 | |
| 2252 int elements_location = JSArray::kSize; | |
| 2253 if (mode == TRACK_ALLOCATION_SITE) { | |
| 2254 elements_location += AllocationMemento::kSize; | |
| 2255 } | |
| 2256 | |
| 2257 HInnerAllocatedObject* elements = Add<HInnerAllocatedObject>( | |
| 2258 array, Add<HConstant>(elements_location)); | |
| 2259 Add<HStoreNamedField>(array, HObjectAccess::ForElementsPointer(), elements); | |
| 2260 return elements; | |
| 2261 } | 2287 } |
| 2262 | 2288 |
| 2263 | 2289 |
| 2264 HInstruction* HGraphBuilder::AddElementAccess( | 2290 HInstruction* HGraphBuilder::AddElementAccess( |
| 2265 HValue* elements, | 2291 HValue* elements, |
| 2266 HValue* checked_key, | 2292 HValue* checked_key, |
| 2267 HValue* val, | 2293 HValue* val, |
| 2268 HValue* dependency, | 2294 HValue* dependency, |
| 2269 ElementsKind elements_kind, | 2295 ElementsKind elements_kind, |
| 2270 bool is_store, | 2296 bool is_store, |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2461 | 2487 |
| 2462 | 2488 |
| 2463 HValue* HGraphBuilder::BuildCloneShallowArray(HValue* boilerplate, | 2489 HValue* HGraphBuilder::BuildCloneShallowArray(HValue* boilerplate, |
| 2464 HValue* allocation_site, | 2490 HValue* allocation_site, |
| 2465 AllocationSiteMode mode, | 2491 AllocationSiteMode mode, |
| 2466 ElementsKind kind, | 2492 ElementsKind kind, |
| 2467 int length) { | 2493 int length) { |
| 2468 NoObservableSideEffectsScope no_effects(this); | 2494 NoObservableSideEffectsScope no_effects(this); |
| 2469 | 2495 |
| 2470 // All sizes here are multiples of kPointerSize. | 2496 // All sizes here are multiples of kPointerSize. |
| 2471 int size = JSArray::kSize; | 2497 HConstant* size_in_bytes = EstablishHeaderAllocationSize(mode); |
| 2472 if (mode == TRACK_ALLOCATION_SITE) { | |
| 2473 size += AllocationMemento::kSize; | |
| 2474 } | |
| 2475 | |
| 2476 HValue* size_in_bytes = Add<HConstant>(size); | |
| 2477 HInstruction* object = Add<HAllocate>(size_in_bytes, | 2498 HInstruction* object = Add<HAllocate>(size_in_bytes, |
| 2478 HType::JSObject(), | 2499 HType::JSObject(), |
| 2479 NOT_TENURED, | 2500 NOT_TENURED, |
| 2480 JS_OBJECT_TYPE); | 2501 JS_OBJECT_TYPE); |
| 2481 | 2502 |
| 2482 // Copy the JS array part. | 2503 // Copy the JS array part. |
| 2483 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { | 2504 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { |
| 2484 if ((i != JSArray::kElementsOffset) || (length == 0)) { | 2505 if ((i != JSArray::kElementsOffset) || (length == 0)) { |
| 2485 HObjectAccess access = HObjectAccess::ForJSArrayOffset(i); | 2506 HObjectAccess access = HObjectAccess::ForJSArrayOffset(i); |
| 2486 Add<HStoreNamedField>(object, access, | 2507 Add<HStoreNamedField>(object, access, |
| 2487 Add<HLoadNamedField>(boilerplate, access)); | 2508 Add<HLoadNamedField>(boilerplate, access)); |
| 2488 } | 2509 } |
| 2489 } | 2510 } |
| 2490 | 2511 |
| 2491 // Create an allocation site info if requested. | 2512 // Create an allocation site info if requested. |
| 2492 if (mode == TRACK_ALLOCATION_SITE) { | 2513 if (mode == TRACK_ALLOCATION_SITE) { |
| 2493 BuildCreateAllocationMemento( | 2514 BuildCreateAllocationMemento( |
| 2494 object, Add<HConstant>(JSArray::kSize), allocation_site); | 2515 object, Add<HConstant>(JSArray::kSize), allocation_site); |
| 2495 } | 2516 } |
| 2496 | 2517 |
| 2497 if (length > 0) { | 2518 if (length > 0) { |
| 2498 HValue* boilerplate_elements = AddLoadElements(boilerplate); | 2519 HValue* boilerplate_elements = AddLoadElements(boilerplate); |
| 2499 HValue* object_elements; | 2520 HConstant* elems_size = EstablishElementsAllocationSize(kind, length); |
| 2500 if (IsFastDoubleElementsKind(kind)) { | 2521 HValue* object_elements = |
| 2501 HValue* elems_size = Add<HConstant>(FixedDoubleArray::SizeFor(length)); | 2522 BuildAllocateElements(kind, elems_size, NOT_TENURED); |
| 2502 object_elements = Add<HAllocate>(elems_size, HType::JSArray(), | 2523 |
| 2503 NOT_TENURED, FIXED_DOUBLE_ARRAY_TYPE); | |
| 2504 } else { | |
| 2505 HValue* elems_size = Add<HConstant>(FixedArray::SizeFor(length)); | |
| 2506 object_elements = Add<HAllocate>(elems_size, HType::JSArray(), | |
| 2507 NOT_TENURED, FIXED_ARRAY_TYPE); | |
| 2508 } | |
| 2509 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), | 2524 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), |
| 2510 object_elements); | 2525 object_elements); |
| 2511 | 2526 |
| 2512 // Copy the elements array header. | 2527 // Copy the elements array header. |
| 2513 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { | 2528 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { |
| 2514 HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i); | 2529 HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i); |
| 2515 Add<HStoreNamedField>(object_elements, access, | 2530 Add<HStoreNamedField>(object_elements, access, |
| 2516 Add<HLoadNamedField>(boilerplate_elements, access)); | 2531 Add<HLoadNamedField>(boilerplate_elements, access)); |
| 2517 } | 2532 } |
| 2518 | 2533 |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2688 } | 2703 } |
| 2689 | 2704 |
| 2690 | 2705 |
| 2691 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { | 2706 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { |
| 2692 // Find the map near the constructor function | 2707 // Find the map near the constructor function |
| 2693 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); | 2708 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); |
| 2694 return builder()->AddLoadNamedField(constructor_function_, access); | 2709 return builder()->AddLoadNamedField(constructor_function_, access); |
| 2695 } | 2710 } |
| 2696 | 2711 |
| 2697 | 2712 |
| 2698 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( | 2713 HAllocate* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() { |
| 2699 HValue* length_node) { | |
| 2700 ASSERT(length_node != NULL); | |
| 2701 | |
| 2702 int base_size = JSArray::kSize; | |
| 2703 if (mode_ == TRACK_ALLOCATION_SITE) { | |
| 2704 base_size += AllocationMemento::kSize; | |
| 2705 } | |
| 2706 | |
| 2707 STATIC_ASSERT(FixedDoubleArray::kHeaderSize == FixedArray::kHeaderSize); | |
| 2708 base_size += FixedArray::kHeaderSize; | |
| 2709 | |
| 2710 HInstruction* elements_size_value = | |
| 2711 builder()->Add<HConstant>(elements_size()); | |
| 2712 HInstruction* mul = HMul::NewImul(builder()->zone(), builder()->context(), | |
| 2713 length_node, elements_size_value); | |
| 2714 builder()->AddInstruction(mul); | |
| 2715 HInstruction* base = builder()->Add<HConstant>(base_size); | |
| 2716 HInstruction* total_size = HAdd::New(builder()->zone(), builder()->context(), | |
| 2717 base, mul); | |
| 2718 total_size->ClearFlag(HValue::kCanOverflow); | |
| 2719 builder()->AddInstruction(total_size); | |
| 2720 return total_size; | |
| 2721 } | |
| 2722 | |
| 2723 | |
| 2724 HValue* HGraphBuilder::JSArrayBuilder::EstablishEmptyArrayAllocationSize() { | |
| 2725 int base_size = JSArray::kSize; | |
| 2726 if (mode_ == TRACK_ALLOCATION_SITE) { | |
| 2727 base_size += AllocationMemento::kSize; | |
| 2728 } | |
| 2729 | |
| 2730 base_size += IsFastDoubleElementsKind(kind_) | |
| 2731 ? FixedDoubleArray::SizeFor(initial_capacity()) | |
| 2732 : FixedArray::SizeFor(initial_capacity()); | |
| 2733 | |
| 2734 return builder()->Add<HConstant>(base_size); | |
| 2735 } | |
| 2736 | |
| 2737 | |
| 2738 HValue* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() { | |
| 2739 HValue* size_in_bytes = EstablishEmptyArrayAllocationSize(); | |
| 2740 HConstant* capacity = builder()->Add<HConstant>(initial_capacity()); | 2714 HConstant* capacity = builder()->Add<HConstant>(initial_capacity()); |
| 2741 return AllocateArray(size_in_bytes, | 2715 return AllocateArray(capacity, |
| 2742 capacity, | |
| 2743 builder()->graph()->GetConstant0()); | 2716 builder()->graph()->GetConstant0()); |
| 2744 } | 2717 } |
| 2745 | 2718 |
| 2746 | 2719 |
| 2747 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* capacity, | 2720 HAllocate* HGraphBuilder::JSArrayBuilder::AllocateArray( |
| 2748 HValue* length_field, | 2721 HValue* capacity, |
| 2749 FillMode fill_mode) { | 2722 HConstant* capacity_upper_bound, |
| 2750 HValue* size_in_bytes = EstablishAllocationSize(capacity); | 2723 HValue* length_field, |
| 2751 return AllocateArray(size_in_bytes, capacity, length_field, fill_mode); | 2724 FillMode fill_mode) { |
| 2725 return AllocateArray(capacity, | |
| 2726 capacity_upper_bound->GetInteger32Constant(), | |
| 2727 length_field, | |
| 2728 fill_mode); | |
| 2752 } | 2729 } |
| 2753 | 2730 |
| 2754 | 2731 |
| 2755 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes, | 2732 HAllocate* HGraphBuilder::JSArrayBuilder::AllocateArray( |
| 2756 HValue* capacity, | 2733 HValue* capacity, |
| 2757 HValue* length_field, | 2734 int capacity_upper_bound, |
| 2758 FillMode fill_mode) { | 2735 HValue* length_field, |
| 2736 FillMode fill_mode) { | |
| 2737 HConstant* elms_size_upper_bound = capacity->IsInteger32Constant() | |
|
Hannes Payer (out of office)
2014/01/16 12:58:39
please use a full name elms -> elements
| |
| 2738 ? HConstant::cast(capacity) | |
| 2739 : builder()->EstablishElementsAllocationSize(kind_, capacity_upper_bound); | |
| 2740 | |
| 2741 HAllocate* array = AllocateArray(capacity, length_field, fill_mode); | |
| 2742 if (!capacity->IsInteger32Constant()) { | |
| 2743 // For constant sizes the size upper bound is set automatically. | |
| 2744 elements_location_->set_size_upper_bound(elms_size_upper_bound); | |
| 2745 } | |
| 2746 return array; | |
| 2747 } | |
| 2748 | |
| 2749 | |
| 2750 HAllocate* HGraphBuilder::JSArrayBuilder::AllocateArray( | |
| 2751 HValue* capacity, | |
| 2752 HValue* length_field, | |
| 2753 FillMode fill_mode) { | |
| 2759 // These HForceRepresentations are because we store these as fields in the | 2754 // These HForceRepresentations are because we store these as fields in the |
| 2760 // objects we construct, and an int32-to-smi HChange could deopt. Accept | 2755 // objects we construct, and an int32-to-smi HChange could deopt. Accept |
| 2761 // the deopt possibility now, before allocation occurs. | 2756 // the deopt possibility now, before allocation occurs. |
| 2762 capacity = | 2757 capacity = |
| 2763 builder()->AddUncasted<HForceRepresentation>(capacity, | 2758 builder()->AddUncasted<HForceRepresentation>(capacity, |
| 2764 Representation::Smi()); | 2759 Representation::Smi()); |
| 2765 length_field = | 2760 length_field = |
| 2766 builder()->AddUncasted<HForceRepresentation>(length_field, | 2761 builder()->AddUncasted<HForceRepresentation>(length_field, |
| 2767 Representation::Smi()); | 2762 Representation::Smi()); |
| 2763 | |
| 2764 // Generate size calculation code here in order to make it dominate | |
| 2765 // the JSArray allocation. | |
| 2766 HValue* elms_size = builder()->BuildCalculateElementsSize(kind_, capacity); | |
|
Hannes Payer (out of office)
2014/01/16 12:58:39
elms -> elements
| |
| 2767 | |
| 2768 // Allocate (dealing with failure appropriately) | 2768 // Allocate (dealing with failure appropriately) |
| 2769 HAllocate* new_object = builder()->Add<HAllocate>(size_in_bytes, | 2769 HConstant* array_object_size = |
| 2770 builder()->EstablishHeaderAllocationSize(mode_); | |
| 2771 HAllocate* array_object = builder()->Add<HAllocate>(array_object_size, | |
| 2770 HType::JSArray(), NOT_TENURED, JS_ARRAY_TYPE); | 2772 HType::JSArray(), NOT_TENURED, JS_ARRAY_TYPE); |
| 2771 | 2773 |
| 2772 // Folded array allocation should be aligned if it has fast double elements. | |
| 2773 if (IsFastDoubleElementsKind(kind_)) { | |
| 2774 new_object->MakeDoubleAligned(); | |
| 2775 } | |
| 2776 | |
| 2777 // Fill in the fields: map, properties, length | 2774 // Fill in the fields: map, properties, length |
| 2778 HValue* map; | 2775 HValue* map; |
| 2779 if (allocation_site_payload_ == NULL) { | 2776 if (allocation_site_payload_ == NULL) { |
| 2780 map = EmitInternalMapCode(); | 2777 map = EmitInternalMapCode(); |
| 2781 } else { | 2778 } else { |
| 2782 map = EmitMapCode(); | 2779 map = EmitMapCode(); |
| 2783 } | 2780 } |
| 2784 elements_location_ = builder()->BuildJSArrayHeader(new_object, | |
| 2785 map, | |
| 2786 mode_, | |
| 2787 kind_, | |
| 2788 allocation_site_payload_, | |
| 2789 length_field); | |
| 2790 | 2781 |
| 2791 // Initialize the elements | 2782 builder()->BuildJSArrayHeader(array_object, |
| 2783 map, | |
| 2784 mode_, | |
| 2785 kind_, | |
| 2786 allocation_site_payload_, | |
| 2787 length_field); | |
| 2788 | |
| 2789 // Allocate and initialize the elements | |
| 2790 elements_location_ = | |
| 2791 builder()->BuildAllocateElements(kind_, elms_size, NOT_TENURED); | |
| 2792 | |
| 2792 builder()->BuildInitializeElementsHeader(elements_location_, kind_, capacity); | 2793 builder()->BuildInitializeElementsHeader(elements_location_, kind_, capacity); |
| 2793 | 2794 |
| 2795 // Set the elements | |
| 2796 builder()->Add<HStoreNamedField>( | |
| 2797 array_object, HObjectAccess::ForElementsPointer(), elements_location_); | |
| 2798 | |
| 2794 if (fill_mode == FILL_WITH_HOLE) { | 2799 if (fill_mode == FILL_WITH_HOLE) { |
| 2795 builder()->BuildFillElementsWithHole(elements_location_, kind_, | 2800 builder()->BuildFillElementsWithHole(elements_location_, kind_, |
| 2796 graph()->GetConstant0(), capacity); | 2801 graph()->GetConstant0(), capacity); |
| 2797 } | 2802 } |
| 2798 | 2803 |
| 2799 return new_object; | 2804 return array_object; |
| 2800 } | 2805 } |
| 2801 | 2806 |
| 2802 | 2807 |
| 2803 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object, | 2808 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object, |
| 2804 Handle<Map> map) { | 2809 Handle<Map> map) { |
| 2805 return Add<HStoreNamedField>(object, HObjectAccess::ForMap(), | 2810 return Add<HStoreNamedField>(object, HObjectAccess::ForMap(), |
| 2806 Add<HConstant>(map)); | 2811 Add<HConstant>(map)); |
| 2807 } | 2812 } |
| 2808 | 2813 |
| 2809 | 2814 |
| (...skipping 7982 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10792 if (ShouldProduceTraceOutput()) { | 10797 if (ShouldProduceTraceOutput()) { |
| 10793 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 10798 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 10794 } | 10799 } |
| 10795 | 10800 |
| 10796 #ifdef DEBUG | 10801 #ifdef DEBUG |
| 10797 graph_->Verify(false); // No full verify. | 10802 graph_->Verify(false); // No full verify. |
| 10798 #endif | 10803 #endif |
| 10799 } | 10804 } |
| 10800 | 10805 |
| 10801 } } // namespace v8::internal | 10806 } } // namespace v8::internal |
| OLD | NEW |