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

Side by Side Diff: src/hydrogen.cc

Issue 272243002: Revert "Reland r20974: Unify and simplify the FastCloneShallowArrayStub" (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 7 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-gvn.cc » ('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 2370 matching lines...) Expand 10 before | Expand all | Expand 10 after
2381 elements, checked_key, dependency, elements_kind, load_mode); 2381 elements, checked_key, dependency, elements_kind, load_mode);
2382 if (FLAG_opt_safe_uint32_operations && 2382 if (FLAG_opt_safe_uint32_operations &&
2383 (elements_kind == EXTERNAL_UINT32_ELEMENTS || 2383 (elements_kind == EXTERNAL_UINT32_ELEMENTS ||
2384 elements_kind == UINT32_ELEMENTS)) { 2384 elements_kind == UINT32_ELEMENTS)) {
2385 graph()->RecordUint32Instruction(load); 2385 graph()->RecordUint32Instruction(load);
2386 } 2386 }
2387 return load; 2387 return load;
2388 } 2388 }
2389 2389
2390 2390
2391 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object, 2391 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object) {
2392 HValue* dependency) {
2393 return Add<HLoadNamedField>( 2392 return Add<HLoadNamedField>(
2394 object, dependency, HObjectAccess::ForElementsPointer()); 2393 object, static_cast<HValue*>(NULL), HObjectAccess::ForElementsPointer());
2395 } 2394 }
2396 2395
2397 2396
2398 HLoadNamedField* HGraphBuilder::AddLoadFixedArrayLength( 2397 HLoadNamedField* HGraphBuilder::AddLoadFixedArrayLength(HValue* object) {
2399 HValue* array,
2400 HValue* dependency) {
2401 return Add<HLoadNamedField>( 2398 return Add<HLoadNamedField>(
2402 array, dependency, HObjectAccess::ForFixedArrayLength()); 2399 object, static_cast<HValue*>(NULL), HObjectAccess::ForFixedArrayLength());
2403 } 2400 }
2404 2401
2405 2402
2406 HLoadNamedField* HGraphBuilder::AddLoadArrayLength(HValue* array,
2407 ElementsKind kind,
2408 HValue* dependency) {
2409 return Add<HLoadNamedField>(
2410 array, dependency, HObjectAccess::ForArrayLength(kind));
2411 }
2412
2413
2414 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* old_capacity) { 2403 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* old_capacity) {
2415 HValue* half_old_capacity = AddUncasted<HShr>(old_capacity, 2404 HValue* half_old_capacity = AddUncasted<HShr>(old_capacity,
2416 graph_->GetConstant1()); 2405 graph_->GetConstant1());
2417 2406
2418 HValue* new_capacity = AddUncasted<HAdd>(half_old_capacity, old_capacity); 2407 HValue* new_capacity = AddUncasted<HAdd>(half_old_capacity, old_capacity);
2419 new_capacity->ClearFlag(HValue::kCanOverflow); 2408 new_capacity->ClearFlag(HValue::kCanOverflow);
2420 2409
2421 HValue* min_growth = Add<HConstant>(16); 2410 HValue* min_growth = Add<HConstant>(16);
2422 2411
2423 new_capacity = AddUncasted<HAdd>(new_capacity, min_growth); 2412 new_capacity = AddUncasted<HAdd>(new_capacity, min_growth);
2424 new_capacity->ClearFlag(HValue::kCanOverflow); 2413 new_capacity->ClearFlag(HValue::kCanOverflow);
2425 2414
2426 return new_capacity; 2415 return new_capacity;
2427 } 2416 }
2428 2417
2429 2418
2430 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, 2419 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object,
2431 HValue* elements, 2420 HValue* elements,
2432 ElementsKind kind, 2421 ElementsKind kind,
2433 ElementsKind new_kind, 2422 ElementsKind new_kind,
2434 HValue* length, 2423 HValue* length,
2435 HValue* new_capacity) { 2424 HValue* new_capacity) {
2436 Add<HBoundsCheck>(new_capacity, Add<HConstant>( 2425 Add<HBoundsCheck>(new_capacity, Add<HConstant>(
2437 (Page::kMaxRegularHeapObjectSize - FixedArray::kHeaderSize) >> 2426 (Page::kMaxRegularHeapObjectSize - FixedArray::kHeaderSize) >>
2438 ElementsKindToShiftSize(kind))); 2427 ElementsKindToShiftSize(kind)));
2439 2428
2440 HValue* new_elements = BuildAllocateElementsAndInitializeElementsHeader( 2429 HValue* new_elements = BuildAllocateElementsAndInitializeElementsHeader(
2441 new_kind, new_capacity); 2430 new_kind, new_capacity);
2442 2431
2443 BuildCopyElements(object, elements, kind, new_elements, 2432 BuildCopyElements(elements, kind,
2444 new_kind, length, new_capacity); 2433 new_elements, new_kind,
2434 length, new_capacity);
2445 2435
2446 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), 2436 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
2447 new_elements); 2437 new_elements);
2448 2438
2449 return new_elements; 2439 return new_elements;
2450 } 2440 }
2451 2441
2452 2442
2453 void HGraphBuilder::BuildFillElementsWithHole(HValue* elements, 2443 void HGraphBuilder::BuildFillElementsWithHole(HValue* elements,
2454 ElementsKind elements_kind, 2444 ElementsKind elements_kind,
2455 HValue* from, 2445 HValue* from,
2456 HValue* to) { 2446 HValue* to) {
2457 // Fast elements kinds need to be initialized in case statements below cause a 2447 // Fast elements kinds need to be initialized in case statements below cause
2458 // garbage collection. 2448 // a garbage collection.
2459 Factory* factory = isolate()->factory(); 2449 Factory* factory = isolate()->factory();
2460 2450
2461 double nan_double = FixedDoubleArray::hole_nan_as_double(); 2451 double nan_double = FixedDoubleArray::hole_nan_as_double();
2462 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) 2452 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind)
2463 ? Add<HConstant>(factory->the_hole_value()) 2453 ? Add<HConstant>(factory->the_hole_value())
2464 : Add<HConstant>(nan_double); 2454 : Add<HConstant>(nan_double);
2465 2455
2466 if (to == NULL) {
2467 to = AddLoadFixedArrayLength(elements);
2468 }
2469
2470 // Special loop unfolding case 2456 // Special loop unfolding case
2471 static const int kLoopUnfoldLimit = 8; 2457 static const int kLoopUnfoldLimit = 8;
2472 STATIC_ASSERT(JSArray::kPreallocatedArrayElements <= kLoopUnfoldLimit); 2458 STATIC_ASSERT(JSArray::kPreallocatedArrayElements <= kLoopUnfoldLimit);
2473 int initial_capacity = -1; 2459 int initial_capacity = -1;
2474 if (from->IsInteger32Constant() && to->IsInteger32Constant()) { 2460 if (from->IsInteger32Constant() && to->IsInteger32Constant()) {
2475 int constant_from = from->GetInteger32Constant(); 2461 int constant_from = from->GetInteger32Constant();
2476 int constant_to = to->GetInteger32Constant(); 2462 int constant_to = to->GetInteger32Constant();
2477 2463
2478 if (constant_from == 0 && constant_to <= kLoopUnfoldLimit) { 2464 if (constant_from == 0 && constant_to <= kLoopUnfoldLimit) {
2479 initial_capacity = constant_to; 2465 initial_capacity = constant_to;
2480 } 2466 }
2481 } 2467 }
2482 2468
2483 // Since we're about to store a hole value, the store instruction below must 2469 // Since we're about to store a hole value, the store instruction below must
2484 // assume an elements kind that supports heap object values. 2470 // assume an elements kind that supports heap object values.
2485 if (IsFastSmiOrObjectElementsKind(elements_kind)) { 2471 if (IsFastSmiOrObjectElementsKind(elements_kind)) {
2486 elements_kind = FAST_HOLEY_ELEMENTS; 2472 elements_kind = FAST_HOLEY_ELEMENTS;
2487 } 2473 }
2488 2474
2489 if (initial_capacity >= 0) { 2475 if (initial_capacity >= 0) {
2490 for (int i = 0; i < initial_capacity; i++) { 2476 for (int i = 0; i < initial_capacity; i++) {
2491 HInstruction* key = Add<HConstant>(i); 2477 HInstruction* key = Add<HConstant>(i);
2492 Add<HStoreKeyed>(elements, key, hole, elements_kind); 2478 Add<HStoreKeyed>(elements, key, hole, elements_kind);
2493 } 2479 }
2494 } else { 2480 } else {
2495 // Carefully loop backwards so that the "from" remains live through the loop 2481 LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement);
2496 // rather than the to. This often corresponds to keeping length live rather
2497 // then capacity, which helps register allocation, since length is used more
2498 // other than capacity after filling with holes.
2499 LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement);
2500 2482
2501 HValue* key = builder.BeginBody(to, from, Token::GT); 2483 HValue* key = builder.BeginBody(from, to, Token::LT);
2502 2484
2503 HValue* adjusted_key = AddUncasted<HSub>(key, graph()->GetConstant1()); 2485 Add<HStoreKeyed>(elements, key, hole, elements_kind);
2504 adjusted_key->ClearFlag(HValue::kCanOverflow);
2505
2506 Add<HStoreKeyed>(elements, adjusted_key, hole, elements_kind);
2507 2486
2508 builder.EndBody(); 2487 builder.EndBody();
2509 } 2488 }
2510 } 2489 }
2511 2490
2512 2491
2513 void HGraphBuilder::BuildCopyElements(HValue* array, 2492 void HGraphBuilder::BuildCopyElements(HValue* from_elements,
2514 HValue* from_elements,
2515 ElementsKind from_elements_kind, 2493 ElementsKind from_elements_kind,
2516 HValue* to_elements, 2494 HValue* to_elements,
2517 ElementsKind to_elements_kind, 2495 ElementsKind to_elements_kind,
2518 HValue* length, 2496 HValue* length,
2519 HValue* capacity) { 2497 HValue* capacity) {
2520 int constant_capacity = -1; 2498 bool pre_fill_with_holes =
2521 if (capacity != NULL &&
2522 capacity->IsConstant() &&
2523 HConstant::cast(capacity)->HasInteger32Value()) {
2524 int constant_candidate = HConstant::cast(capacity)->Integer32Value();
2525 if (constant_candidate <=
2526 FastCloneShallowArrayStub::kMaximumInlinedCloneLength) {
2527 constant_capacity = constant_candidate;
2528 }
2529 }
2530
2531 if (constant_capacity != -1) {
2532 // Unroll the loop for small elements kinds.
2533 for (int i = 0; i < constant_capacity; i++) {
2534 HValue* key_constant = Add<HConstant>(i);
2535 HInstruction* value = Add<HLoadKeyed>(from_elements, key_constant,
2536 static_cast<HValue*>(NULL),
2537 from_elements_kind);
2538 Add<HStoreKeyed>(to_elements, key_constant, value, to_elements_kind);
2539 }
2540 } else {
2541 bool pre_fill_with_holes =
2542 IsFastDoubleElementsKind(from_elements_kind) && 2499 IsFastDoubleElementsKind(from_elements_kind) &&
2543 IsFastObjectElementsKind(to_elements_kind); 2500 IsFastObjectElementsKind(to_elements_kind);
2544 2501
2545 if (pre_fill_with_holes) { 2502 if (pre_fill_with_holes) {
2546 // If the copy might trigger a GC, make sure that the FixedArray is 2503 // If the copy might trigger a GC, make sure that the FixedArray is
2547 // pre-initialized with holes to make sure that it's always in a 2504 // pre-initialized with holes to make sure that it's always in a consistent
2548 // consistent state. 2505 // state.
2549 BuildFillElementsWithHole(to_elements, to_elements_kind, 2506 BuildFillElementsWithHole(to_elements, to_elements_kind,
2550 graph()->GetConstant0(), NULL); 2507 graph()->GetConstant0(), capacity);
2551 } else if (capacity == NULL || !length->Equals(capacity)) { 2508 }
2552 BuildFillElementsWithHole(to_elements, to_elements_kind,
2553 length, NULL);
2554 }
2555 2509
2556 if (capacity == NULL) { 2510 LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement);
2557 capacity = AddLoadFixedArrayLength(to_elements);
2558 }
2559 2511
2560 LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement); 2512 HValue* key = builder.BeginBody(graph()->GetConstant0(), length, Token::LT);
2561 2513
2562 HValue* key = builder.BeginBody(length, graph()->GetConstant0(), 2514 HValue* element = Add<HLoadKeyed>(from_elements, key,
2563 Token::GT); 2515 static_cast<HValue*>(NULL),
2516 from_elements_kind,
2517 ALLOW_RETURN_HOLE);
2564 2518
2565 key = AddUncasted<HSub>(key, graph()->GetConstant1()); 2519 ElementsKind kind = (IsHoleyElementsKind(from_elements_kind) &&
2566 key->ClearFlag(HValue::kCanOverflow); 2520 IsFastSmiElementsKind(to_elements_kind))
2567
2568 HValue* element = Add<HLoadKeyed>(from_elements, key,
2569 static_cast<HValue*>(NULL),
2570 from_elements_kind,
2571 ALLOW_RETURN_HOLE);
2572
2573 ElementsKind kind = (IsHoleyElementsKind(from_elements_kind) &&
2574 IsFastSmiElementsKind(to_elements_kind))
2575 ? FAST_HOLEY_ELEMENTS : to_elements_kind; 2521 ? FAST_HOLEY_ELEMENTS : to_elements_kind;
2576 2522
2577 if (IsHoleyElementsKind(from_elements_kind) && 2523 if (IsHoleyElementsKind(from_elements_kind) &&
2578 from_elements_kind != to_elements_kind) { 2524 from_elements_kind != to_elements_kind) {
2579 IfBuilder if_hole(this); 2525 IfBuilder if_hole(this);
2580 if_hole.If<HCompareHoleAndBranch>(element); 2526 if_hole.If<HCompareHoleAndBranch>(element);
2581 if_hole.Then(); 2527 if_hole.Then();
2582 HConstant* hole_constant = IsFastDoubleElementsKind(to_elements_kind) 2528 HConstant* hole_constant = IsFastDoubleElementsKind(to_elements_kind)
2583 ? Add<HConstant>(FixedDoubleArray::hole_nan_as_double()) 2529 ? Add<HConstant>(FixedDoubleArray::hole_nan_as_double())
2584 : graph()->GetConstantHole(); 2530 : graph()->GetConstantHole();
2585 Add<HStoreKeyed>(to_elements, key, hole_constant, kind); 2531 Add<HStoreKeyed>(to_elements, key, hole_constant, kind);
2586 if_hole.Else(); 2532 if_hole.Else();
2587 HStoreKeyed* store = Add<HStoreKeyed>(to_elements, key, element, kind); 2533 HStoreKeyed* store = Add<HStoreKeyed>(to_elements, key, element, kind);
2588 store->SetFlag(HValue::kAllowUndefinedAsNaN); 2534 store->SetFlag(HValue::kAllowUndefinedAsNaN);
2589 if_hole.End(); 2535 if_hole.End();
2590 } else { 2536 } else {
2591 HStoreKeyed* store = Add<HStoreKeyed>(to_elements, key, element, kind); 2537 HStoreKeyed* store = Add<HStoreKeyed>(to_elements, key, element, kind);
2592 store->SetFlag(HValue::kAllowUndefinedAsNaN); 2538 store->SetFlag(HValue::kAllowUndefinedAsNaN);
2593 }
2594
2595 builder.EndBody();
2596 } 2539 }
2597 2540
2598 Counters* counters = isolate()->counters(); 2541 builder.EndBody();
2599 AddIncrementCounter(counters->inlined_copied_elements()); 2542
2543 if (!pre_fill_with_holes && length != capacity) {
2544 // Fill unused capacity with the hole.
2545 BuildFillElementsWithHole(to_elements, to_elements_kind,
2546 key, capacity);
2547 }
2600 } 2548 }
2601 2549
2602 HValue* HGraphBuilder::BuildCloneShallowArrayCommon( 2550
2603 HValue* boilerplate, 2551 HValue* HGraphBuilder::BuildCloneShallowArray(HValue* boilerplate,
2604 HValue* allocation_site, 2552 HValue* allocation_site,
2605 HValue* extra_size, 2553 AllocationSiteMode mode,
2606 HValue** return_elements, 2554 ElementsKind kind,
2607 AllocationSiteMode mode) { 2555 int length) {
2556 NoObservableSideEffectsScope no_effects(this);
2557
2608 // All sizes here are multiples of kPointerSize. 2558 // All sizes here are multiples of kPointerSize.
2609 int array_size = JSArray::kSize; 2559 int size = JSArray::kSize;
2610 if (mode == TRACK_ALLOCATION_SITE) { 2560 if (mode == TRACK_ALLOCATION_SITE) {
2611 array_size += AllocationMemento::kSize; 2561 size += AllocationMemento::kSize;
2612 } 2562 }
2613 2563
2614 HValue* size_in_bytes = Add<HConstant>(array_size); 2564 HValue* size_in_bytes = Add<HConstant>(size);
2615 if (extra_size != NULL) {
2616 size_in_bytes = AddUncasted<HAdd>(extra_size, size_in_bytes);
2617 size_in_bytes->ClearFlag(HValue::kCanOverflow);
2618 }
2619
2620 HInstruction* object = Add<HAllocate>(size_in_bytes, 2565 HInstruction* object = Add<HAllocate>(size_in_bytes,
2621 HType::JSObject(), 2566 HType::JSObject(),
2622 NOT_TENURED, 2567 NOT_TENURED,
2623 JS_OBJECT_TYPE); 2568 JS_OBJECT_TYPE);
2624 2569
2625 // Copy the JS array part. 2570 // Copy the JS array part.
2626 HValue* map = Add<HLoadNamedField>(boilerplate, 2571 for (int i = 0; i < JSArray::kSize; i += kPointerSize) {
2627 static_cast<HValue*>(NULL), HObjectAccess::ForMap()); 2572 if ((i != JSArray::kElementsOffset) || (length == 0)) {
2628 Add<HStoreNamedField>(object, HObjectAccess::ForPropertiesPointer(), 2573 HObjectAccess access = HObjectAccess::ForJSArrayOffset(i);
2629 Add<HConstant>(isolate()->factory()->empty_fixed_array()), 2574 Add<HStoreNamedField>(
2630 INITIALIZING_STORE); 2575 object, access, Add<HLoadNamedField>(
2631 Add<HStoreNamedField>(object, HObjectAccess::ForMap(), map, 2576 boilerplate, static_cast<HValue*>(NULL), access));
2632 INITIALIZING_STORE); 2577 }
2578 }
2633 2579
2634 // Create an allocation site info if requested. 2580 // Create an allocation site info if requested.
2635 if (mode == TRACK_ALLOCATION_SITE) { 2581 if (mode == TRACK_ALLOCATION_SITE) {
2636 BuildCreateAllocationMemento( 2582 BuildCreateAllocationMemento(
2637 object, Add<HConstant>(JSArray::kSize), allocation_site); 2583 object, Add<HConstant>(JSArray::kSize), allocation_site);
2638 } 2584 }
2639 2585
2640 if (extra_size != NULL) { 2586 if (length > 0) {
2641 HValue* elements = Add<HInnerAllocatedObject>(object, 2587 // We have to initialize the elements pointer if allocation folding is
2642 Add<HConstant>(array_size)); 2588 // turned off.
2643 if (return_elements != NULL) *return_elements = elements; 2589 if (!FLAG_use_gvn || !FLAG_use_allocation_folding) {
2590 HConstant* empty_fixed_array = Add<HConstant>(
2591 isolate()->factory()->empty_fixed_array());
2592 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
2593 empty_fixed_array, INITIALIZING_STORE);
2594 }
2595
2596 HValue* boilerplate_elements = AddLoadElements(boilerplate);
2597 HValue* object_elements;
2598 if (IsFastDoubleElementsKind(kind)) {
2599 HValue* elems_size = Add<HConstant>(FixedDoubleArray::SizeFor(length));
2600 object_elements = Add<HAllocate>(elems_size, HType::Tagged(),
2601 NOT_TENURED, FIXED_DOUBLE_ARRAY_TYPE);
2602 } else {
2603 HValue* elems_size = Add<HConstant>(FixedArray::SizeFor(length));
2604 object_elements = Add<HAllocate>(elems_size, HType::Tagged(),
2605 NOT_TENURED, FIXED_ARRAY_TYPE);
2606 }
2607 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
2608 object_elements);
2609
2610 // Copy the elements array header.
2611 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) {
2612 HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i);
2613 Add<HStoreNamedField>(
2614 object_elements, access, Add<HLoadNamedField>(
2615 boilerplate_elements, static_cast<HValue*>(NULL), access));
2616 }
2617
2618 // Copy the elements array contents.
2619 // TODO(mstarzinger): Teach HGraphBuilder::BuildCopyElements to unfold
2620 // copying loops with constant length up to a given boundary and use this
2621 // helper here instead.
2622 for (int i = 0; i < length; i++) {
2623 HValue* key_constant = Add<HConstant>(i);
2624 HInstruction* value = Add<HLoadKeyed>(boilerplate_elements, key_constant,
2625 static_cast<HValue*>(NULL), kind);
2626 Add<HStoreKeyed>(object_elements, key_constant, value, kind);
2627 }
2644 } 2628 }
2645 2629
2646 return object; 2630 return object;
2647 } 2631 }
2648 2632
2649 2633
2650 HValue* HGraphBuilder::BuildCloneShallowArrayCow(HValue* boilerplate,
2651 HValue* allocation_site,
2652 AllocationSiteMode mode,
2653 ElementsKind kind) {
2654 HValue* result = BuildCloneShallowArrayCommon(boilerplate,
2655 allocation_site, NULL, NULL, mode);
2656
2657 HValue* elements = AddLoadElements(boilerplate);
2658 HObjectAccess access = HObjectAccess::ForElementsPointer();
2659 Add<HStoreNamedField>(result, access, elements, INITIALIZING_STORE);
2660
2661 HValue* length = AddLoadArrayLength(boilerplate, kind);
2662 access = HObjectAccess::ForArrayLength(kind);
2663 Add<HStoreNamedField>(result, access, length, INITIALIZING_STORE);
2664
2665 return result;
2666 }
2667
2668
2669 HValue* HGraphBuilder::BuildCloneShallowArrayEmpty(HValue* boilerplate,
2670 HValue* allocation_site,
2671 AllocationSiteMode mode) {
2672 HValue* result = BuildCloneShallowArrayCommon(boilerplate,
2673 allocation_site, NULL, NULL, mode);
2674
2675 HObjectAccess access = HObjectAccess::ForArrayLength(FAST_ELEMENTS);
2676 Add<HStoreNamedField>(result, access, graph()->GetConstant0(),
2677 INITIALIZING_STORE);
2678 access = HObjectAccess::ForElementsPointer();
2679 Add<HStoreNamedField>(result, access,
2680 Add<HConstant>(isolate()->factory()->empty_fixed_array()),
2681 INITIALIZING_STORE);
2682
2683 return result;
2684 }
2685
2686
2687 HValue* HGraphBuilder::BuildCloneShallowArrayNonEmpty(HValue* boilerplate,
2688 HValue* allocation_site,
2689 AllocationSiteMode mode,
2690 ElementsKind kind) {
2691 int elements_kind_size = IsFastDoubleElementsKind(kind)
2692 ? kDoubleSize : kPointerSize;
2693
2694 HValue* boilerplate_elements = AddLoadElements(boilerplate);
2695 HValue* capacity = AddLoadFixedArrayLength(boilerplate_elements);
2696 HValue* extra = AddUncasted<HMul>(capacity,
2697 Add<HConstant>(elements_kind_size));
2698 extra->ClearFlag(HValue::kCanOverflow);
2699 extra = AddUncasted<HAdd>(extra, Add<HConstant>(FixedArray::kHeaderSize));
2700 extra->ClearFlag(HValue::kCanOverflow);
2701 HValue* elements = NULL;
2702 HValue* result = BuildCloneShallowArrayCommon(boilerplate,
2703 allocation_site, extra, &elements, mode);
2704 Add<HStoreNamedField>(result, HObjectAccess::ForElementsPointer(),
2705 elements, INITIALIZING_STORE);
2706
2707 // The allocation for the cloned array above causes register pressure on
2708 // machines with low register counts. Force a reload of the boilerplate
2709 // elements here to free up a register for the allocation to avoid unnecessary
2710 // spillage.
2711 boilerplate_elements = AddLoadElements(boilerplate);
2712 boilerplate_elements->SetFlag(HValue::kCantBeReplaced);
2713
2714 // Copy the elements array header.
2715 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) {
2716 HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i);
2717 Add<HStoreNamedField>(elements, access,
2718 Add<HLoadNamedField>(boilerplate_elements,
2719 static_cast<HValue*>(NULL), access),
2720 INITIALIZING_STORE);
2721 }
2722
2723 // And the result of the length
2724 HValue* length = Add<HLoadNamedField>(boilerplate, static_cast<HValue*>(NULL),
2725 HObjectAccess::ForArrayLength(kind));
2726 Add<HStoreNamedField>(result, HObjectAccess::ForArrayLength(kind),
2727 length, INITIALIZING_STORE);
2728
2729 BuildCopyElements(result, boilerplate_elements, kind, elements,
2730 kind, length, NULL);
2731
2732 return result;
2733 }
2734
2735
2736 void HGraphBuilder::BuildCompareNil( 2634 void HGraphBuilder::BuildCompareNil(
2737 HValue* value, 2635 HValue* value,
2738 Type* type, 2636 Type* type,
2739 HIfContinuation* continuation) { 2637 HIfContinuation* continuation) {
2740 IfBuilder if_nil(this); 2638 IfBuilder if_nil(this);
2741 bool some_case_handled = false; 2639 bool some_case_handled = false;
2742 bool some_case_missing = false; 2640 bool some_case_missing = false;
2743 2641
2744 if (type->Maybe(Type::Null())) { 2642 if (type->Maybe(Type::Null())) {
2745 if (some_case_handled) if_nil.Or(); 2643 if (some_case_handled) if_nil.Or();
(...skipping 9051 matching lines...) Expand 10 before | Expand all | Expand 10 after
11797 if (ShouldProduceTraceOutput()) { 11695 if (ShouldProduceTraceOutput()) {
11798 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 11696 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
11799 } 11697 }
11800 11698
11801 #ifdef DEBUG 11699 #ifdef DEBUG
11802 graph_->Verify(false); // No full verify. 11700 graph_->Verify(false); // No full verify.
11803 #endif 11701 #endif
11804 } 11702 }
11805 11703
11806 } } // namespace v8::internal 11704 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-gvn.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698