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

Side by Side Diff: src/hydrogen.cc

Issue 304153009: Implemented folding of constant size allocation followed by dynamic size allocation. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: TODO removed Created 6 years, 6 months 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
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "hydrogen.h" 5 #include "hydrogen.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "v8.h" 9 #include "v8.h"
10 #include "allocation-site-scopes.h" 10 #include "allocation-site-scopes.h"
(...skipping 1517 matching lines...) Expand 10 before | Expand all | Expand 10 after
1528 1528
1529 return BuildUncheckedDictionaryElementLoadHelper(elements, key, 1529 return BuildUncheckedDictionaryElementLoadHelper(elements, key,
1530 hash, mask, 0); 1530 hash, mask, 0);
1531 } 1531 }
1532 1532
1533 1533
1534 HValue* HGraphBuilder::BuildRegExpConstructResult(HValue* length, 1534 HValue* HGraphBuilder::BuildRegExpConstructResult(HValue* length,
1535 HValue* index, 1535 HValue* index,
1536 HValue* input) { 1536 HValue* input) {
1537 NoObservableSideEffectsScope scope(this); 1537 NoObservableSideEffectsScope scope(this);
1538 HConstant* max_length = Add<HConstant>(JSObject::kInitialMaxFastElementArray);
1539 Add<HBoundsCheck>(length, max_length);
1538 1540
1539 // Compute the size of the RegExpResult followed by FixedArray with length. 1541 // Generate size calculation code here in order to make it dominate
1540 HValue* size = length; 1542 // the JSRegExpResult allocation.
1541 // Make sure size does not exceed max regular heap object size. 1543 ElementsKind elements_kind = FAST_ELEMENTS;
1542 const int kHeaderSize = JSRegExpResult::kSize + FixedArray::kHeaderSize; 1544 HValue* size = BuildCalculateElementsSize(elements_kind, length);
1543 const int kMaxLength =
1544 (Page::kMaxRegularHeapObjectSize - kHeaderSize) >> kPointerSizeLog2;
1545 Add<HBoundsCheck>(size, Add<HConstant>(kMaxLength));
1546
1547 size = AddUncasted<HShl>(size, Add<HConstant>(kPointerSizeLog2));
1548 size = AddUncasted<HAdd>(size, Add<HConstant>(kHeaderSize));
1549 1545
1550 // Allocate the JSRegExpResult and the FixedArray in one step. 1546 // Allocate the JSRegExpResult and the FixedArray in one step.
1551 HValue* result = Add<HAllocate>( 1547 HValue* result = Add<HAllocate>(
1552 size, HType::JSArray(), NOT_TENURED, JS_ARRAY_TYPE); 1548 Add<HConstant>(JSRegExpResult::kSize), HType::JSArray(),
1553 1549 NOT_TENURED, JS_ARRAY_TYPE);
1554 // Determine the elements FixedArray.
1555 HValue* elements = Add<HInnerAllocatedObject>(
1556 result, Add<HConstant>(JSRegExpResult::kSize), HType::HeapObject());
1557 1550
1558 // Initialize the JSRegExpResult header. 1551 // Initialize the JSRegExpResult header.
1559 HValue* global_object = Add<HLoadNamedField>( 1552 HValue* global_object = Add<HLoadNamedField>(
1560 context(), static_cast<HValue*>(NULL), 1553 context(), static_cast<HValue*>(NULL),
1561 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); 1554 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
1562 HValue* native_context = Add<HLoadNamedField>( 1555 HValue* native_context = Add<HLoadNamedField>(
1563 global_object, static_cast<HValue*>(NULL), 1556 global_object, static_cast<HValue*>(NULL),
1564 HObjectAccess::ForGlobalObjectNativeContext()); 1557 HObjectAccess::ForGlobalObjectNativeContext());
1565 Add<HStoreNamedField>( 1558 Add<HStoreNamedField>(
1566 result, HObjectAccess::ForMap(), 1559 result, HObjectAccess::ForMap(),
1567 Add<HLoadNamedField>( 1560 Add<HLoadNamedField>(
1568 native_context, static_cast<HValue*>(NULL), 1561 native_context, static_cast<HValue*>(NULL),
1569 HObjectAccess::ForContextSlot(Context::REGEXP_RESULT_MAP_INDEX))); 1562 HObjectAccess::ForContextSlot(Context::REGEXP_RESULT_MAP_INDEX)));
1563 HConstant* empty_fixed_array =
1564 Add<HConstant>(isolate()->factory()->empty_fixed_array());
1570 Add<HStoreNamedField>( 1565 Add<HStoreNamedField>(
1571 result, HObjectAccess::ForJSArrayOffset(JSArray::kPropertiesOffset), 1566 result, HObjectAccess::ForJSArrayOffset(JSArray::kPropertiesOffset),
1572 Add<HConstant>(isolate()->factory()->empty_fixed_array())); 1567 empty_fixed_array);
1573 Add<HStoreNamedField>( 1568 Add<HStoreNamedField>(
1574 result, HObjectAccess::ForJSArrayOffset(JSArray::kElementsOffset), 1569 result, HObjectAccess::ForJSArrayOffset(JSArray::kElementsOffset),
1575 elements); 1570 empty_fixed_array);
1576 Add<HStoreNamedField>( 1571 Add<HStoreNamedField>(
1577 result, HObjectAccess::ForJSArrayOffset(JSArray::kLengthOffset), length); 1572 result, HObjectAccess::ForJSArrayOffset(JSArray::kLengthOffset), length);
1578 1573
1579 // Initialize the additional fields. 1574 // Initialize the additional fields.
1580 Add<HStoreNamedField>( 1575 Add<HStoreNamedField>(
1581 result, HObjectAccess::ForJSArrayOffset(JSRegExpResult::kIndexOffset), 1576 result, HObjectAccess::ForJSArrayOffset(JSRegExpResult::kIndexOffset),
1582 index); 1577 index);
1583 Add<HStoreNamedField>( 1578 Add<HStoreNamedField>(
1584 result, HObjectAccess::ForJSArrayOffset(JSRegExpResult::kInputOffset), 1579 result, HObjectAccess::ForJSArrayOffset(JSRegExpResult::kInputOffset),
1585 input); 1580 input);
1586 1581
1587 // Initialize the elements header. 1582 // Allocate and initialize the elements header.
1588 AddStoreMapConstant(elements, isolate()->factory()->fixed_array_map()); 1583 HAllocate* elements = BuildAllocateElements(elements_kind, size);
1589 Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(), length); 1584 BuildInitializeElementsHeader(elements, elements_kind, length);
1585
1586 HConstant* size_in_bytes_upper_bound = EstablishElementsAllocationSize(
1587 elements_kind, max_length->Integer32Value());
1588 elements->set_size_upper_bound(size_in_bytes_upper_bound);
1589
1590 Add<HStoreNamedField>(
1591 result, HObjectAccess::ForJSArrayOffset(JSArray::kElementsOffset),
1592 elements);
1590 1593
1591 // Initialize the elements contents with undefined. 1594 // Initialize the elements contents with undefined.
1592 LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement); 1595 BuildFillElementsWithValue(
1593 index = loop.BeginBody(graph()->GetConstant0(), length, Token::LT); 1596 elements, elements_kind, graph()->GetConstant0(), length,
1594 { 1597 graph()->GetConstantUndefined());
1595 Add<HStoreKeyed>(elements, index, graph()->GetConstantUndefined(),
1596 FAST_ELEMENTS);
1597 }
1598 loop.EndBody();
1599 1598
1600 return result; 1599 return result;
1601 } 1600 }
1602 1601
1603 1602
1604 HValue* HGraphBuilder::BuildNumberToString(HValue* object, Type* type) { 1603 HValue* HGraphBuilder::BuildNumberToString(HValue* object, Type* type) {
1605 NoObservableSideEffectsScope scope(this); 1604 NoObservableSideEffectsScope scope(this);
1606 1605
1607 // Convert constant numbers at compile time. 1606 // Convert constant numbers at compile time.
1608 if (object->IsConstant() && HConstant::cast(object)->HasNumberValue()) { 1607 if (object->IsConstant() && HConstant::cast(object)->HasNumberValue()) {
(...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after
2221 elements, isolate()->factory()->fixed_array_map()); 2220 elements, isolate()->factory()->fixed_array_map());
2222 check_cow_map->ClearDependsOnFlag(kElementsKind); 2221 check_cow_map->ClearDependsOnFlag(kElementsKind);
2223 } 2222 }
2224 } 2223 }
2225 } 2224 }
2226 return AddElementAccess(elements, checked_key, val, checked_object, 2225 return AddElementAccess(elements, checked_key, val, checked_object,
2227 elements_kind, access_type, load_mode); 2226 elements_kind, access_type, load_mode);
2228 } 2227 }
2229 2228
2230 2229
2231
2232 HValue* HGraphBuilder::BuildAllocateArrayFromLength( 2230 HValue* HGraphBuilder::BuildAllocateArrayFromLength(
2233 JSArrayBuilder* array_builder, 2231 JSArrayBuilder* array_builder,
2234 HValue* length_argument) { 2232 HValue* length_argument) {
2235 if (length_argument->IsConstant() && 2233 if (length_argument->IsConstant() &&
2236 HConstant::cast(length_argument)->HasSmiValue()) { 2234 HConstant::cast(length_argument)->HasSmiValue()) {
2237 int array_length = HConstant::cast(length_argument)->Integer32Value(); 2235 int array_length = HConstant::cast(length_argument)->Integer32Value();
2238 HValue* new_object = array_length == 0 2236 if (array_length == 0) {
2239 ? array_builder->AllocateEmptyArray() 2237 return array_builder->AllocateEmptyArray();
2240 : array_builder->AllocateArray(length_argument, length_argument); 2238 } else {
2241 return new_object; 2239 return array_builder->AllocateArray(length_argument,
2240 array_length,
2241 length_argument);
2242 }
2242 } 2243 }
2243 2244
2244 HValue* constant_zero = graph()->GetConstant0(); 2245 HValue* constant_zero = graph()->GetConstant0();
2245 HConstant* max_alloc_length = 2246 HConstant* max_alloc_length =
2246 Add<HConstant>(JSObject::kInitialMaxFastElementArray); 2247 Add<HConstant>(JSObject::kInitialMaxFastElementArray);
2247 HInstruction* checked_length = Add<HBoundsCheck>(length_argument, 2248 HInstruction* checked_length = Add<HBoundsCheck>(length_argument,
2248 max_alloc_length); 2249 max_alloc_length);
2249 IfBuilder if_builder(this); 2250 IfBuilder if_builder(this);
2250 if_builder.If<HCompareNumericAndBranch>(checked_length, constant_zero, 2251 if_builder.If<HCompareNumericAndBranch>(checked_length, constant_zero,
2251 Token::EQ); 2252 Token::EQ);
2252 if_builder.Then(); 2253 if_builder.Then();
2253 const int initial_capacity = JSArray::kPreallocatedArrayElements; 2254 const int initial_capacity = JSArray::kPreallocatedArrayElements;
2254 HConstant* initial_capacity_node = Add<HConstant>(initial_capacity); 2255 HConstant* initial_capacity_node = Add<HConstant>(initial_capacity);
2255 Push(initial_capacity_node); // capacity 2256 Push(initial_capacity_node); // capacity
2256 Push(constant_zero); // length 2257 Push(constant_zero); // length
2257 if_builder.Else(); 2258 if_builder.Else();
2258 if (!(top_info()->IsStub()) && 2259 if (!(top_info()->IsStub()) &&
2259 IsFastPackedElementsKind(array_builder->kind())) { 2260 IsFastPackedElementsKind(array_builder->kind())) {
2260 // We'll come back later with better (holey) feedback. 2261 // We'll come back later with better (holey) feedback.
2261 if_builder.Deopt("Holey array despite packed elements_kind feedback"); 2262 if_builder.Deopt("Holey array despite packed elements_kind feedback");
2262 } else { 2263 } else {
2263 Push(checked_length); // capacity 2264 Push(checked_length); // capacity
2264 Push(checked_length); // length 2265 Push(checked_length); // length
2265 } 2266 }
2266 if_builder.End(); 2267 if_builder.End();
2267 2268
2268 // Figure out total size 2269 // Figure out total size
2269 HValue* length = Pop(); 2270 HValue* length = Pop();
2270 HValue* capacity = Pop(); 2271 HValue* capacity = Pop();
2271 return array_builder->AllocateArray(capacity, length); 2272 return array_builder->AllocateArray(capacity, max_alloc_length, length);
2272 } 2273 }
2273 2274
2274 2275
2275 HValue* HGraphBuilder::BuildAllocateElements(ElementsKind kind, 2276 HValue* HGraphBuilder::BuildCalculateElementsSize(ElementsKind kind,
2276 HValue* capacity) { 2277 HValue* capacity) {
2277 int elements_size; 2278 int elements_size = IsFastDoubleElementsKind(kind)
2278 InstanceType instance_type; 2279 ? kDoubleSize
2279 2280 : kPointerSize;
2280 if (IsFastDoubleElementsKind(kind)) {
2281 elements_size = kDoubleSize;
2282 instance_type = FIXED_DOUBLE_ARRAY_TYPE;
2283 } else {
2284 elements_size = kPointerSize;
2285 instance_type = FIXED_ARRAY_TYPE;
2286 }
2287 2281
2288 HConstant* elements_size_value = Add<HConstant>(elements_size); 2282 HConstant* elements_size_value = Add<HConstant>(elements_size);
2289 HValue* mul = AddUncasted<HMul>(capacity, elements_size_value); 2283 HInstruction* mul = HMul::NewImul(zone(), context(),
2284 capacity->ActualValue(),
2285 elements_size_value);
2286 AddInstruction(mul);
2290 mul->ClearFlag(HValue::kCanOverflow); 2287 mul->ClearFlag(HValue::kCanOverflow);
2291 2288
2289 STATIC_ASSERT(FixedDoubleArray::kHeaderSize == FixedArray::kHeaderSize);
2290
2292 HConstant* header_size = Add<HConstant>(FixedArray::kHeaderSize); 2291 HConstant* header_size = Add<HConstant>(FixedArray::kHeaderSize);
2293 HValue* total_size = AddUncasted<HAdd>(mul, header_size); 2292 HValue* total_size = AddUncasted<HAdd>(mul, header_size);
2294 total_size->ClearFlag(HValue::kCanOverflow); 2293 total_size->ClearFlag(HValue::kCanOverflow);
2294 return total_size;
2295 }
2295 2296
2296 return Add<HAllocate>(total_size, HType::HeapObject(), NOT_TENURED, 2297
2298 HAllocate* HGraphBuilder::AllocateJSArrayObject(AllocationSiteMode mode) {
2299 int base_size = JSArray::kSize;
2300 if (mode == TRACK_ALLOCATION_SITE) {
2301 base_size += AllocationMemento::kSize;
2302 }
2303 HConstant* size_in_bytes = Add<HConstant>(base_size);
2304 return Add<HAllocate>(
2305 size_in_bytes, HType::JSArray(), NOT_TENURED, JS_OBJECT_TYPE);
2306 }
2307
2308
2309 HConstant* HGraphBuilder::EstablishElementsAllocationSize(
2310 ElementsKind kind,
2311 int capacity) {
2312 int base_size = IsFastDoubleElementsKind(kind)
2313 ? FixedDoubleArray::SizeFor(capacity)
2314 : FixedArray::SizeFor(capacity);
2315
2316 return Add<HConstant>(base_size);
2317 }
2318
2319
2320 HAllocate* HGraphBuilder::BuildAllocateElements(ElementsKind kind,
2321 HValue* size_in_bytes) {
2322 InstanceType instance_type = IsFastDoubleElementsKind(kind)
2323 ? FIXED_DOUBLE_ARRAY_TYPE
2324 : FIXED_ARRAY_TYPE;
2325
2326 return Add<HAllocate>(size_in_bytes, HType::HeapObject(), NOT_TENURED,
2297 instance_type); 2327 instance_type);
2298 } 2328 }
2299 2329
2300 2330
2301 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements, 2331 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements,
2302 ElementsKind kind, 2332 ElementsKind kind,
2303 HValue* capacity) { 2333 HValue* capacity) {
2304 Factory* factory = isolate()->factory(); 2334 Factory* factory = isolate()->factory();
2305 Handle<Map> map = IsFastDoubleElementsKind(kind) 2335 Handle<Map> map = IsFastDoubleElementsKind(kind)
2306 ? factory->fixed_double_array_map() 2336 ? factory->fixed_double_array_map()
2307 : factory->fixed_array_map(); 2337 : factory->fixed_array_map();
2308 2338
2309 Add<HStoreNamedField>(elements, HObjectAccess::ForMap(), Add<HConstant>(map)); 2339 Add<HStoreNamedField>(elements, HObjectAccess::ForMap(), Add<HConstant>(map));
2310 Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(), 2340 Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(),
2311 capacity); 2341 capacity);
2312 } 2342 }
2313 2343
2314 2344
2315 HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader( 2345 HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader(
2316 ElementsKind kind, 2346 ElementsKind kind,
2317 HValue* capacity) { 2347 HValue* capacity) {
2318 // The HForceRepresentation is to prevent possible deopt on int-smi 2348 // The HForceRepresentation is to prevent possible deopt on int-smi
2319 // conversion after allocation but before the new object fields are set. 2349 // conversion after allocation but before the new object fields are set.
2320 capacity = AddUncasted<HForceRepresentation>(capacity, Representation::Smi()); 2350 capacity = AddUncasted<HForceRepresentation>(capacity, Representation::Smi());
2321 HValue* new_elements = BuildAllocateElements(kind, capacity); 2351 HValue* size_in_bytes = BuildCalculateElementsSize(kind, capacity);
2352 HValue* new_elements = BuildAllocateElements(kind, size_in_bytes);
2322 BuildInitializeElementsHeader(new_elements, kind, capacity); 2353 BuildInitializeElementsHeader(new_elements, kind, capacity);
2323 return new_elements; 2354 return new_elements;
2324 } 2355 }
2325 2356
2326 2357
2327 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array, 2358 void HGraphBuilder::BuildJSArrayHeader(HValue* array,
2328 HValue* array_map, 2359 HValue* array_map,
2329 AllocationSiteMode mode, 2360 HValue* elements,
2330 ElementsKind elements_kind, 2361 AllocationSiteMode mode,
2331 HValue* allocation_site_payload, 2362 ElementsKind elements_kind,
2332 HValue* length_field) { 2363 HValue* allocation_site_payload,
2333 2364 HValue* length_field) {
2334 Add<HStoreNamedField>(array, HObjectAccess::ForMap(), array_map); 2365 Add<HStoreNamedField>(array, HObjectAccess::ForMap(), array_map);
2335 2366
2336 HConstant* empty_fixed_array = 2367 HConstant* empty_fixed_array =
2337 Add<HConstant>(isolate()->factory()->empty_fixed_array()); 2368 Add<HConstant>(isolate()->factory()->empty_fixed_array());
2338 2369
2339 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); 2370 Add<HStoreNamedField>(
2340 Add<HStoreNamedField>(array, access, empty_fixed_array); 2371 array, HObjectAccess::ForPropertiesPointer(), empty_fixed_array);
2341 Add<HStoreNamedField>(array, HObjectAccess::ForArrayLength(elements_kind), 2372
2342 length_field); 2373 Add<HStoreNamedField>(
2374 array, HObjectAccess::ForElementsPointer(),
2375 elements != NULL ? elements : empty_fixed_array);
2376
2377 Add<HStoreNamedField>(
2378 array, HObjectAccess::ForArrayLength(elements_kind), length_field);
2343 2379
2344 if (mode == TRACK_ALLOCATION_SITE) { 2380 if (mode == TRACK_ALLOCATION_SITE) {
2345 BuildCreateAllocationMemento( 2381 BuildCreateAllocationMemento(
2346 array, Add<HConstant>(JSArray::kSize), allocation_site_payload); 2382 array, Add<HConstant>(JSArray::kSize), allocation_site_payload);
2347 } 2383 }
2348
2349 int elements_location = JSArray::kSize;
2350 if (mode == TRACK_ALLOCATION_SITE) {
2351 elements_location += AllocationMemento::kSize;
2352 }
2353
2354 HInnerAllocatedObject* elements = Add<HInnerAllocatedObject>(
2355 array, Add<HConstant>(elements_location), HType::HeapObject());
2356 Add<HStoreNamedField>(array, HObjectAccess::ForElementsPointer(), elements);
2357 return elements;
2358 } 2384 }
2359 2385
2360 2386
2361 HInstruction* HGraphBuilder::AddElementAccess( 2387 HInstruction* HGraphBuilder::AddElementAccess(
2362 HValue* elements, 2388 HValue* elements,
2363 HValue* checked_key, 2389 HValue* checked_key,
2364 HValue* val, 2390 HValue* val,
2365 HValue* dependency, 2391 HValue* dependency,
2366 ElementsKind elements_kind, 2392 ElementsKind elements_kind,
2367 PropertyAccessType access_type, 2393 PropertyAccessType access_type,
(...skipping 16 matching lines...) Expand all
2384 elements, checked_key, dependency, elements_kind, load_mode); 2410 elements, checked_key, dependency, elements_kind, load_mode);
2385 if (FLAG_opt_safe_uint32_operations && 2411 if (FLAG_opt_safe_uint32_operations &&
2386 (elements_kind == EXTERNAL_UINT32_ELEMENTS || 2412 (elements_kind == EXTERNAL_UINT32_ELEMENTS ||
2387 elements_kind == UINT32_ELEMENTS)) { 2413 elements_kind == UINT32_ELEMENTS)) {
2388 graph()->RecordUint32Instruction(load); 2414 graph()->RecordUint32Instruction(load);
2389 } 2415 }
2390 return load; 2416 return load;
2391 } 2417 }
2392 2418
2393 2419
2420 HLoadNamedField* HGraphBuilder::AddLoadMap(HValue* object,
2421 HValue* dependency) {
2422 return Add<HLoadNamedField>(object, dependency, HObjectAccess::ForMap());
2423 }
2424
2425
2394 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object, 2426 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object,
2395 HValue* dependency) { 2427 HValue* dependency) {
2396 return Add<HLoadNamedField>( 2428 return Add<HLoadNamedField>(
2397 object, dependency, HObjectAccess::ForElementsPointer()); 2429 object, dependency, HObjectAccess::ForElementsPointer());
2398 } 2430 }
2399 2431
2400 2432
2401 HLoadNamedField* HGraphBuilder::AddLoadFixedArrayLength( 2433 HLoadNamedField* HGraphBuilder::AddLoadFixedArrayLength(
2402 HValue* array, 2434 HValue* array,
2403 HValue* dependency) { 2435 HValue* dependency) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2436 ElementsKind new_kind, 2468 ElementsKind new_kind,
2437 HValue* length, 2469 HValue* length,
2438 HValue* new_capacity) { 2470 HValue* new_capacity) {
2439 Add<HBoundsCheck>(new_capacity, Add<HConstant>( 2471 Add<HBoundsCheck>(new_capacity, Add<HConstant>(
2440 (Page::kMaxRegularHeapObjectSize - FixedArray::kHeaderSize) >> 2472 (Page::kMaxRegularHeapObjectSize - FixedArray::kHeaderSize) >>
2441 ElementsKindToShiftSize(kind))); 2473 ElementsKindToShiftSize(kind)));
2442 2474
2443 HValue* new_elements = BuildAllocateElementsAndInitializeElementsHeader( 2475 HValue* new_elements = BuildAllocateElementsAndInitializeElementsHeader(
2444 new_kind, new_capacity); 2476 new_kind, new_capacity);
2445 2477
2446 BuildCopyElements(object, elements, kind, new_elements, 2478 BuildCopyElements(elements, kind, new_elements,
2447 new_kind, length, new_capacity); 2479 new_kind, length, new_capacity);
2448 2480
2449 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), 2481 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
2450 new_elements); 2482 new_elements);
2451 2483
2452 return new_elements; 2484 return new_elements;
2453 } 2485 }
2454 2486
2455 2487
2456 void HGraphBuilder::BuildFillElementsWithHole(HValue* elements, 2488 void HGraphBuilder::BuildFillElementsWithValue(HValue* elements,
2457 ElementsKind elements_kind, 2489 ElementsKind elements_kind,
2458 HValue* from, 2490 HValue* from,
2459 HValue* to) { 2491 HValue* to,
2460 // Fast elements kinds need to be initialized in case statements below cause a 2492 HValue* value) {
2461 // garbage collection.
2462 Factory* factory = isolate()->factory();
2463
2464 double nan_double = FixedDoubleArray::hole_nan_as_double();
2465 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind)
2466 ? Add<HConstant>(factory->the_hole_value())
2467 : Add<HConstant>(nan_double);
2468
2469 if (to == NULL) { 2493 if (to == NULL) {
2470 to = AddLoadFixedArrayLength(elements); 2494 to = AddLoadFixedArrayLength(elements);
2471 } 2495 }
2472 2496
2473 // Special loop unfolding case 2497 // Special loop unfolding case
2474 STATIC_ASSERT(JSArray::kPreallocatedArrayElements <= 2498 STATIC_ASSERT(JSArray::kPreallocatedArrayElements <=
2475 kElementLoopUnrollThreshold); 2499 kElementLoopUnrollThreshold);
2476 int initial_capacity = -1; 2500 int initial_capacity = -1;
2477 if (from->IsInteger32Constant() && to->IsInteger32Constant()) { 2501 if (from->IsInteger32Constant() && to->IsInteger32Constant()) {
2478 int constant_from = from->GetInteger32Constant(); 2502 int constant_from = from->GetInteger32Constant();
2479 int constant_to = to->GetInteger32Constant(); 2503 int constant_to = to->GetInteger32Constant();
2480 2504
2481 if (constant_from == 0 && constant_to <= kElementLoopUnrollThreshold) { 2505 if (constant_from == 0 && constant_to <= kElementLoopUnrollThreshold) {
2482 initial_capacity = constant_to; 2506 initial_capacity = constant_to;
2483 } 2507 }
2484 } 2508 }
2485 2509
2486 // Since we're about to store a hole value, the store instruction below must 2510 // Since we're about to store a hole value, the store instruction below must
2487 // assume an elements kind that supports heap object values. 2511 // assume an elements kind that supports heap object values.
2488 if (IsFastSmiOrObjectElementsKind(elements_kind)) { 2512 if (IsFastSmiOrObjectElementsKind(elements_kind)) {
2489 elements_kind = FAST_HOLEY_ELEMENTS; 2513 elements_kind = FAST_HOLEY_ELEMENTS;
2490 } 2514 }
2491 2515
2492 if (initial_capacity >= 0) { 2516 if (initial_capacity >= 0) {
2493 for (int i = 0; i < initial_capacity; i++) { 2517 for (int i = 0; i < initial_capacity; i++) {
2494 HInstruction* key = Add<HConstant>(i); 2518 HInstruction* key = Add<HConstant>(i);
2495 Add<HStoreKeyed>(elements, key, hole, elements_kind); 2519 Add<HStoreKeyed>(elements, key, value, elements_kind);
2496 } 2520 }
2497 } else { 2521 } else {
2498 // Carefully loop backwards so that the "from" remains live through the loop 2522 // Carefully loop backwards so that the "from" remains live through the loop
2499 // rather than the to. This often corresponds to keeping length live rather 2523 // rather than the to. This often corresponds to keeping length live rather
2500 // then capacity, which helps register allocation, since length is used more 2524 // then capacity, which helps register allocation, since length is used more
2501 // other than capacity after filling with holes. 2525 // other than capacity after filling with holes.
2502 LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement); 2526 LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement);
2503 2527
2504 HValue* key = builder.BeginBody(to, from, Token::GT); 2528 HValue* key = builder.BeginBody(to, from, Token::GT);
2505 2529
2506 HValue* adjusted_key = AddUncasted<HSub>(key, graph()->GetConstant1()); 2530 HValue* adjusted_key = AddUncasted<HSub>(key, graph()->GetConstant1());
2507 adjusted_key->ClearFlag(HValue::kCanOverflow); 2531 adjusted_key->ClearFlag(HValue::kCanOverflow);
2508 2532
2509 Add<HStoreKeyed>(elements, adjusted_key, hole, elements_kind); 2533 Add<HStoreKeyed>(elements, adjusted_key, value, elements_kind);
2510 2534
2511 builder.EndBody(); 2535 builder.EndBody();
2512 } 2536 }
2513 } 2537 }
2514 2538
2515 2539
2516 void HGraphBuilder::BuildCopyElements(HValue* array, 2540 void HGraphBuilder::BuildFillElementsWithHole(HValue* elements,
2517 HValue* from_elements, 2541 ElementsKind elements_kind,
2542 HValue* from,
2543 HValue* to) {
2544 // Fast elements kinds need to be initialized in case statements below cause a
2545 // garbage collection.
2546 Factory* factory = isolate()->factory();
2547
2548 double nan_double = FixedDoubleArray::hole_nan_as_double();
2549 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind)
2550 ? Add<HConstant>(factory->the_hole_value())
2551 : Add<HConstant>(nan_double);
2552
2553 BuildFillElementsWithValue(elements, elements_kind, from, to, hole);
2554 }
2555
2556
2557 void HGraphBuilder::BuildCopyElements(HValue* from_elements,
2518 ElementsKind from_elements_kind, 2558 ElementsKind from_elements_kind,
2519 HValue* to_elements, 2559 HValue* to_elements,
2520 ElementsKind to_elements_kind, 2560 ElementsKind to_elements_kind,
2521 HValue* length, 2561 HValue* length,
2522 HValue* capacity) { 2562 HValue* capacity) {
2523 int constant_capacity = -1; 2563 int constant_capacity = -1;
2524 if (capacity != NULL && 2564 if (capacity != NULL &&
2525 capacity->IsConstant() && 2565 capacity->IsConstant() &&
2526 HConstant::cast(capacity)->HasInteger32Value()) { 2566 HConstant::cast(capacity)->HasInteger32Value()) {
2527 int constant_candidate = HConstant::cast(capacity)->Integer32Value(); 2567 int constant_candidate = HConstant::cast(capacity)->Integer32Value();
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
2594 store->SetFlag(HValue::kAllowUndefinedAsNaN); 2634 store->SetFlag(HValue::kAllowUndefinedAsNaN);
2595 } 2635 }
2596 2636
2597 builder.EndBody(); 2637 builder.EndBody();
2598 } 2638 }
2599 2639
2600 Counters* counters = isolate()->counters(); 2640 Counters* counters = isolate()->counters();
2601 AddIncrementCounter(counters->inlined_copied_elements()); 2641 AddIncrementCounter(counters->inlined_copied_elements());
2602 } 2642 }
2603 2643
2604 HValue* HGraphBuilder::BuildCloneShallowArrayCommon(
2605 HValue* boilerplate,
2606 HValue* allocation_site,
2607 HValue* extra_size,
2608 HValue** return_elements,
2609 AllocationSiteMode mode) {
2610 // All sizes here are multiples of kPointerSize.
2611 int array_size = JSArray::kSize;
2612 if (mode == TRACK_ALLOCATION_SITE) {
2613 array_size += AllocationMemento::kSize;
2614 }
2615
2616 HValue* size_in_bytes = Add<HConstant>(array_size);
2617 if (extra_size != NULL) {
2618 size_in_bytes = AddUncasted<HAdd>(extra_size, size_in_bytes);
2619 size_in_bytes->ClearFlag(HValue::kCanOverflow);
2620 }
2621
2622 HInstruction* object = Add<HAllocate>(size_in_bytes,
2623 HType::JSObject(),
2624 NOT_TENURED,
2625 JS_OBJECT_TYPE);
2626
2627 // Copy the JS array part.
2628 HValue* map = Add<HLoadNamedField>(boilerplate,
2629 static_cast<HValue*>(NULL), HObjectAccess::ForMap());
2630 Add<HStoreNamedField>(object, HObjectAccess::ForPropertiesPointer(),
2631 Add<HConstant>(isolate()->factory()->empty_fixed_array()),
2632 INITIALIZING_STORE);
2633 Add<HStoreNamedField>(object, HObjectAccess::ForMap(), map,
2634 INITIALIZING_STORE);
2635
2636 // Create an allocation site info if requested.
2637 if (mode == TRACK_ALLOCATION_SITE) {
2638 BuildCreateAllocationMemento(
2639 object, Add<HConstant>(JSArray::kSize), allocation_site);
2640 }
2641
2642 if (extra_size != NULL) {
2643 HValue* elements = Add<HInnerAllocatedObject>(object,
2644 Add<HConstant>(array_size), HType::HeapObject());
2645 if (return_elements != NULL) *return_elements = elements;
2646 }
2647
2648 return object;
2649 }
2650
2651 2644
2652 HValue* HGraphBuilder::BuildCloneShallowArrayCow(HValue* boilerplate, 2645 HValue* HGraphBuilder::BuildCloneShallowArrayCow(HValue* boilerplate,
2653 HValue* allocation_site, 2646 HValue* allocation_site,
2654 AllocationSiteMode mode, 2647 AllocationSiteMode mode,
2655 ElementsKind kind) { 2648 ElementsKind kind) {
2656 HValue* result = BuildCloneShallowArrayCommon(boilerplate, 2649 HAllocate* array = AllocateJSArrayObject(mode);
2657 allocation_site, NULL, NULL, mode);
2658 2650
2651 HValue* map = AddLoadMap(boilerplate);
2659 HValue* elements = AddLoadElements(boilerplate); 2652 HValue* elements = AddLoadElements(boilerplate);
2660 HObjectAccess access = HObjectAccess::ForElementsPointer(); 2653 HValue* length = AddLoadArrayLength(boilerplate, kind);
2661 Add<HStoreNamedField>(result, access, elements, INITIALIZING_STORE);
2662 2654
2663 HValue* length = AddLoadArrayLength(boilerplate, kind); 2655 BuildJSArrayHeader(array,
2664 access = HObjectAccess::ForArrayLength(kind); 2656 map,
2665 Add<HStoreNamedField>(result, access, length, INITIALIZING_STORE); 2657 elements,
2666 2658 mode,
2667 return result; 2659 FAST_ELEMENTS,
2660 allocation_site,
2661 length);
2662 return array;
2668 } 2663 }
2669 2664
2670 2665
2671 HValue* HGraphBuilder::BuildCloneShallowArrayEmpty(HValue* boilerplate, 2666 HValue* HGraphBuilder::BuildCloneShallowArrayEmpty(HValue* boilerplate,
2672 HValue* allocation_site, 2667 HValue* allocation_site,
2673 AllocationSiteMode mode) { 2668 AllocationSiteMode mode) {
2674 HValue* result = BuildCloneShallowArrayCommon(boilerplate, 2669 HAllocate* array = AllocateJSArrayObject(mode);
2675 allocation_site, NULL, NULL, mode);
2676 2670
2677 HObjectAccess access = HObjectAccess::ForArrayLength(FAST_ELEMENTS); 2671 HValue* map = AddLoadMap(boilerplate);
2678 Add<HStoreNamedField>(result, access, graph()->GetConstant0(),
2679 INITIALIZING_STORE);
2680 access = HObjectAccess::ForElementsPointer();
2681 Add<HStoreNamedField>(result, access,
2682 Add<HConstant>(isolate()->factory()->empty_fixed_array()),
2683 INITIALIZING_STORE);
2684 2672
2685 return result; 2673 BuildJSArrayHeader(array,
2674 map,
2675 NULL, // set elements to empty fixed array
2676 mode,
2677 FAST_ELEMENTS,
2678 allocation_site,
2679 graph()->GetConstant0());
2680 return array;
2686 } 2681 }
2687 2682
2688 2683
2689 HValue* HGraphBuilder::BuildCloneShallowArrayNonEmpty(HValue* boilerplate, 2684 HValue* HGraphBuilder::BuildCloneShallowArrayNonEmpty(HValue* boilerplate,
2690 HValue* allocation_site, 2685 HValue* allocation_site,
2691 AllocationSiteMode mode, 2686 AllocationSiteMode mode,
2692 ElementsKind kind) { 2687 ElementsKind kind) {
2693 int elements_kind_size = IsFastDoubleElementsKind(kind)
2694 ? kDoubleSize : kPointerSize;
2695
2696 HValue* boilerplate_elements = AddLoadElements(boilerplate); 2688 HValue* boilerplate_elements = AddLoadElements(boilerplate);
2697 HValue* capacity = AddLoadFixedArrayLength(boilerplate_elements); 2689 HValue* capacity = AddLoadFixedArrayLength(boilerplate_elements);
2698 HValue* extra = AddUncasted<HMul>(capacity, 2690
2699 Add<HConstant>(elements_kind_size)); 2691 // Generate size calculation code here in order to make it dominate
2700 extra->ClearFlag(HValue::kCanOverflow); 2692 // the JSArray allocation.
2701 extra = AddUncasted<HAdd>(extra, Add<HConstant>(FixedArray::kHeaderSize)); 2693 HValue* elements_size = BuildCalculateElementsSize(kind, capacity);
2702 extra->ClearFlag(HValue::kCanOverflow); 2694
2695 // Create empty JSArray object for now, store elimination should remove
2696 // redundant initialization of elements and length fields and at the same
2697 // time the object will be fully prepared for GC if it happens during
2698 // elements allocation.
2699 HValue* result = BuildCloneShallowArrayEmpty(
2700 boilerplate, allocation_site, mode);
2701
2702 HAllocate* elements = BuildAllocateElements(kind, elements_size);
2703
2703 // This function implicitly relies on the fact that the 2704 // This function implicitly relies on the fact that the
2704 // FastCloneShallowArrayStub is called only for literals shorter than 2705 // FastCloneShallowArrayStub is called only for literals shorter than
2705 // JSObject::kInitialMaxFastElementArray and therefore the size of the 2706 // JSObject::kInitialMaxFastElementArray.
2706 // resulting folded allocation will always be in allowed range.
2707 // Can't add HBoundsCheck here because otherwise the stub will eager a frame. 2707 // Can't add HBoundsCheck here because otherwise the stub will eager a frame.
2708 HConstant* size_upper_bound = EstablishElementsAllocationSize(
2709 kind, JSObject::kInitialMaxFastElementArray);
2710 elements->set_size_upper_bound(size_upper_bound);
2708 2711
2709 HValue* elements = NULL; 2712 Add<HStoreNamedField>(result, HObjectAccess::ForElementsPointer(), elements);
2710 HValue* result = BuildCloneShallowArrayCommon(boilerplate,
2711 allocation_site, extra, &elements, mode);
2712 Add<HStoreNamedField>(result, HObjectAccess::ForElementsPointer(),
2713 elements, INITIALIZING_STORE);
2714 2713
2715 // The allocation for the cloned array above causes register pressure on 2714 // The allocation for the cloned array above causes register pressure on
2716 // machines with low register counts. Force a reload of the boilerplate 2715 // machines with low register counts. Force a reload of the boilerplate
2717 // elements here to free up a register for the allocation to avoid unnecessary 2716 // elements here to free up a register for the allocation to avoid unnecessary
2718 // spillage. 2717 // spillage.
2719 boilerplate_elements = AddLoadElements(boilerplate); 2718 boilerplate_elements = AddLoadElements(boilerplate);
2720 boilerplate_elements->SetFlag(HValue::kCantBeReplaced); 2719 boilerplate_elements->SetFlag(HValue::kCantBeReplaced);
2721 2720
2722 // Copy the elements array header. 2721 // Copy the elements array header.
2723 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { 2722 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) {
2724 HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i); 2723 HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i);
2725 Add<HStoreNamedField>(elements, access, 2724 Add<HStoreNamedField>(elements, access,
2726 Add<HLoadNamedField>(boilerplate_elements, 2725 Add<HLoadNamedField>(boilerplate_elements,
2727 static_cast<HValue*>(NULL), access), 2726 static_cast<HValue*>(NULL), access));
2728 INITIALIZING_STORE);
2729 } 2727 }
2730 2728
2731 // And the result of the length 2729 // And the result of the length
2732 HValue* length = Add<HLoadNamedField>(boilerplate, static_cast<HValue*>(NULL), 2730 HValue* length = AddLoadArrayLength(boilerplate, kind);
2733 HObjectAccess::ForArrayLength(kind)); 2731 Add<HStoreNamedField>(result, HObjectAccess::ForArrayLength(kind), length);
2734 Add<HStoreNamedField>(result, HObjectAccess::ForArrayLength(kind),
2735 length, INITIALIZING_STORE);
2736 2732
2737 BuildCopyElements(result, boilerplate_elements, kind, elements, 2733 BuildCopyElements(boilerplate_elements, kind, elements,
2738 kind, length, NULL); 2734 kind, length, NULL);
2739
2740 return result; 2735 return result;
2741 } 2736 }
2742 2737
2743 2738
2744 void HGraphBuilder::BuildCompareNil( 2739 void HGraphBuilder::BuildCompareNil(
2745 HValue* value, 2740 HValue* value,
2746 Type* type, 2741 Type* type,
2747 HIfContinuation* continuation) { 2742 HIfContinuation* continuation) {
2748 IfBuilder if_nil(this); 2743 IfBuilder if_nil(this);
2749 bool some_case_handled = false; 2744 bool some_case_handled = false;
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
2924 2919
2925 2920
2926 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { 2921 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() {
2927 // Find the map near the constructor function 2922 // Find the map near the constructor function
2928 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); 2923 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
2929 return builder()->Add<HLoadNamedField>( 2924 return builder()->Add<HLoadNamedField>(
2930 constructor_function_, static_cast<HValue*>(NULL), access); 2925 constructor_function_, static_cast<HValue*>(NULL), access);
2931 } 2926 }
2932 2927
2933 2928
2934 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( 2929 HAllocate* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() {
2935 HValue* length_node) {
2936 ASSERT(length_node != NULL);
2937
2938 int base_size = JSArray::kSize;
2939 if (mode_ == TRACK_ALLOCATION_SITE) {
2940 base_size += AllocationMemento::kSize;
2941 }
2942
2943 STATIC_ASSERT(FixedDoubleArray::kHeaderSize == FixedArray::kHeaderSize);
2944 base_size += FixedArray::kHeaderSize;
2945
2946 HInstruction* elements_size_value =
2947 builder()->Add<HConstant>(elements_size());
2948 HInstruction* mul = HMul::NewImul(builder()->zone(), builder()->context(),
2949 length_node, elements_size_value);
2950 builder()->AddInstruction(mul);
2951 HInstruction* base = builder()->Add<HConstant>(base_size);
2952 HInstruction* total_size = HAdd::New(builder()->zone(), builder()->context(),
2953 base, mul);
2954 total_size->ClearFlag(HValue::kCanOverflow);
2955 builder()->AddInstruction(total_size);
2956 return total_size;
2957 }
2958
2959
2960 HValue* HGraphBuilder::JSArrayBuilder::EstablishEmptyArrayAllocationSize() {
2961 int base_size = JSArray::kSize;
2962 if (mode_ == TRACK_ALLOCATION_SITE) {
2963 base_size += AllocationMemento::kSize;
2964 }
2965
2966 base_size += IsFastDoubleElementsKind(kind_)
2967 ? FixedDoubleArray::SizeFor(initial_capacity())
2968 : FixedArray::SizeFor(initial_capacity());
2969
2970 return builder()->Add<HConstant>(base_size);
2971 }
2972
2973
2974 HValue* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() {
2975 HValue* size_in_bytes = EstablishEmptyArrayAllocationSize();
2976 HConstant* capacity = builder()->Add<HConstant>(initial_capacity()); 2930 HConstant* capacity = builder()->Add<HConstant>(initial_capacity());
2977 return AllocateArray(size_in_bytes, 2931 return AllocateArray(capacity,
2978 capacity, 2932 capacity,
2979 builder()->graph()->GetConstant0()); 2933 builder()->graph()->GetConstant0());
2980 } 2934 }
2981 2935
2982 2936
2983 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* capacity, 2937 HAllocate* HGraphBuilder::JSArrayBuilder::AllocateArray(
2984 HValue* length_field, 2938 HValue* capacity,
2985 FillMode fill_mode) { 2939 HConstant* capacity_upper_bound,
2986 HValue* size_in_bytes = EstablishAllocationSize(capacity); 2940 HValue* length_field,
2987 return AllocateArray(size_in_bytes, capacity, length_field, fill_mode); 2941 FillMode fill_mode) {
2942 return AllocateArray(capacity,
2943 capacity_upper_bound->GetInteger32Constant(),
2944 length_field,
2945 fill_mode);
2988 } 2946 }
2989 2947
2990 2948
2991 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes, 2949 HAllocate* HGraphBuilder::JSArrayBuilder::AllocateArray(
2992 HValue* capacity, 2950 HValue* capacity,
2993 HValue* length_field, 2951 int capacity_upper_bound,
2994 FillMode fill_mode) { 2952 HValue* length_field,
2953 FillMode fill_mode) {
2954 HConstant* elememts_size_upper_bound = capacity->IsInteger32Constant()
2955 ? HConstant::cast(capacity)
2956 : builder()->EstablishElementsAllocationSize(kind_, capacity_upper_bound);
2957
2958 HAllocate* array = AllocateArray(capacity, length_field, fill_mode);
2959 if (!elements_location_->has_size_upper_bound()) {
2960 elements_location_->set_size_upper_bound(elememts_size_upper_bound);
2961 }
2962 return array;
2963 }
2964
2965
2966 HAllocate* HGraphBuilder::JSArrayBuilder::AllocateArray(
2967 HValue* capacity,
2968 HValue* length_field,
2969 FillMode fill_mode) {
2995 // These HForceRepresentations are because we store these as fields in the 2970 // These HForceRepresentations are because we store these as fields in the
2996 // objects we construct, and an int32-to-smi HChange could deopt. Accept 2971 // objects we construct, and an int32-to-smi HChange could deopt. Accept
2997 // the deopt possibility now, before allocation occurs. 2972 // the deopt possibility now, before allocation occurs.
2998 capacity = 2973 capacity =
2999 builder()->AddUncasted<HForceRepresentation>(capacity, 2974 builder()->AddUncasted<HForceRepresentation>(capacity,
3000 Representation::Smi()); 2975 Representation::Smi());
3001 length_field = 2976 length_field =
3002 builder()->AddUncasted<HForceRepresentation>(length_field, 2977 builder()->AddUncasted<HForceRepresentation>(length_field,
3003 Representation::Smi()); 2978 Representation::Smi());
2979
2980 // Generate size calculation code here in order to make it dominate
2981 // the JSArray allocation.
2982 HValue* elements_size =
2983 builder()->BuildCalculateElementsSize(kind_, capacity);
2984
3004 // Allocate (dealing with failure appropriately) 2985 // Allocate (dealing with failure appropriately)
3005 HAllocate* new_object = builder()->Add<HAllocate>(size_in_bytes, 2986 HAllocate* array_object = builder()->AllocateJSArrayObject(mode_);
3006 HType::JSArray(), NOT_TENURED, JS_ARRAY_TYPE);
3007
3008 // Folded array allocation should be aligned if it has fast double elements.
3009 if (IsFastDoubleElementsKind(kind_)) {
3010 new_object->MakeDoubleAligned();
3011 }
3012 2987
3013 // Fill in the fields: map, properties, length 2988 // Fill in the fields: map, properties, length
3014 HValue* map; 2989 HValue* map;
3015 if (allocation_site_payload_ == NULL) { 2990 if (allocation_site_payload_ == NULL) {
3016 map = EmitInternalMapCode(); 2991 map = EmitInternalMapCode();
3017 } else { 2992 } else {
3018 map = EmitMapCode(); 2993 map = EmitMapCode();
3019 } 2994 }
3020 elements_location_ = builder()->BuildJSArrayHeader(new_object,
3021 map,
3022 mode_,
3023 kind_,
3024 allocation_site_payload_,
3025 length_field);
3026 2995
3027 // Initialize the elements 2996 builder()->BuildJSArrayHeader(array_object,
2997 map,
2998 NULL, // set elements to empty fixed array
2999 mode_,
3000 kind_,
3001 allocation_site_payload_,
3002 length_field);
3003
3004 // Allocate and initialize the elements
3005 elements_location_ = builder()->BuildAllocateElements(kind_, elements_size);
3006
3028 builder()->BuildInitializeElementsHeader(elements_location_, kind_, capacity); 3007 builder()->BuildInitializeElementsHeader(elements_location_, kind_, capacity);
3029 3008
3009 // Set the elements
3010 builder()->Add<HStoreNamedField>(
3011 array_object, HObjectAccess::ForElementsPointer(), elements_location_);
3012
3030 if (fill_mode == FILL_WITH_HOLE) { 3013 if (fill_mode == FILL_WITH_HOLE) {
3031 builder()->BuildFillElementsWithHole(elements_location_, kind_, 3014 builder()->BuildFillElementsWithHole(elements_location_, kind_,
3032 graph()->GetConstant0(), capacity); 3015 graph()->GetConstant0(), capacity);
3033 } 3016 }
3034 3017
3035 return new_object; 3018 return array_object;
3036 } 3019 }
3037 3020
3038 3021
3039 HValue* HGraphBuilder::AddLoadJSBuiltin(Builtins::JavaScript builtin) { 3022 HValue* HGraphBuilder::AddLoadJSBuiltin(Builtins::JavaScript builtin) {
3040 HValue* global_object = Add<HLoadNamedField>( 3023 HValue* global_object = Add<HLoadNamedField>(
3041 context(), static_cast<HValue*>(NULL), 3024 context(), static_cast<HValue*>(NULL),
3042 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); 3025 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
3043 HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset( 3026 HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset(
3044 GlobalObject::kBuiltinsOffset); 3027 GlobalObject::kBuiltinsOffset);
3045 HValue* builtins = Add<HLoadNamedField>( 3028 HValue* builtins = Add<HLoadNamedField>(
(...skipping 7194 matching lines...) Expand 10 before | Expand all | Expand 10 after
10240 HInstruction* object = Add<HAllocate>(object_size_constant, type, 10223 HInstruction* object = Add<HAllocate>(object_size_constant, type,
10241 pretenure_flag, instance_type, site_context->current()); 10224 pretenure_flag, instance_type, site_context->current());
10242 10225
10243 // If allocation folding reaches Page::kMaxRegularHeapObjectSize the 10226 // If allocation folding reaches Page::kMaxRegularHeapObjectSize the
10244 // elements array may not get folded into the object. Hence, we set the 10227 // elements array may not get folded into the object. Hence, we set the
10245 // elements pointer to empty fixed array and let store elimination remove 10228 // elements pointer to empty fixed array and let store elimination remove
10246 // this store in the folding case. 10229 // this store in the folding case.
10247 HConstant* empty_fixed_array = Add<HConstant>( 10230 HConstant* empty_fixed_array = Add<HConstant>(
10248 isolate()->factory()->empty_fixed_array()); 10231 isolate()->factory()->empty_fixed_array());
10249 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), 10232 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
10250 empty_fixed_array, INITIALIZING_STORE); 10233 empty_fixed_array);
10251 10234
10252 BuildEmitObjectHeader(boilerplate_object, object); 10235 BuildEmitObjectHeader(boilerplate_object, object);
10253 10236
10254 Handle<FixedArrayBase> elements(boilerplate_object->elements()); 10237 Handle<FixedArrayBase> elements(boilerplate_object->elements());
10255 int elements_size = (elements->length() > 0 && 10238 int elements_size = (elements->length() > 0 &&
10256 elements->map() != isolate()->heap()->fixed_cow_array_map()) ? 10239 elements->map() != isolate()->heap()->fixed_cow_array_map()) ?
10257 elements->Size() : 0; 10240 elements->Size() : 0;
10258 10241
10259 if (pretenure_flag == TENURED && 10242 if (pretenure_flag == TENURED &&
10260 elements->map() == isolate()->heap()->fixed_cow_array_map() && 10243 elements->map() == isolate()->heap()->fixed_cow_array_map() &&
(...skipping 1527 matching lines...) Expand 10 before | Expand all | Expand 10 after
11788 if (ShouldProduceTraceOutput()) { 11771 if (ShouldProduceTraceOutput()) {
11789 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 11772 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
11790 } 11773 }
11791 11774
11792 #ifdef DEBUG 11775 #ifdef DEBUG
11793 graph_->Verify(false); // No full verify. 11776 graph_->Verify(false); // No full verify.
11794 #endif 11777 #endif
11795 } 11778 }
11796 11779
11797 } } // namespace v8::internal 11780 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698