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

Side by Side Diff: src/hydrogen.cc

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

Powered by Google App Engine
This is Rietveld 408576698