| OLD | NEW |
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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 #include "src/code-stub-assembler.h" | 4 #include "src/code-stub-assembler.h" |
| 5 #include "src/code-factory.h" | 5 #include "src/code-factory.h" |
| 6 #include "src/frames-inl.h" | 6 #include "src/frames-inl.h" |
| 7 #include "src/frames.h" | 7 #include "src/frames.h" |
| 8 | 8 |
| 9 namespace v8 { | 9 namespace v8 { |
| 10 namespace internal { | 10 namespace internal { |
| (...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 431 | 431 |
| 432 Node* CodeStubAssembler::SmiToWord32(Node* value) { | 432 Node* CodeStubAssembler::SmiToWord32(Node* value) { |
| 433 Node* result = SmiUntag(value); | 433 Node* result = SmiUntag(value); |
| 434 return TruncateWordToWord32(result); | 434 return TruncateWordToWord32(result); |
| 435 } | 435 } |
| 436 | 436 |
| 437 Node* CodeStubAssembler::SmiToFloat64(Node* value) { | 437 Node* CodeStubAssembler::SmiToFloat64(Node* value) { |
| 438 return ChangeInt32ToFloat64(SmiToWord32(value)); | 438 return ChangeInt32ToFloat64(SmiToWord32(value)); |
| 439 } | 439 } |
| 440 | 440 |
| 441 Node* CodeStubAssembler::SmiAdd(Node* a, Node* b) { | |
| 442 return BitcastWordToTaggedSigned( | |
| 443 IntPtrAdd(BitcastTaggedToWord(a), BitcastTaggedToWord(b))); | |
| 444 } | |
| 445 | |
| 446 Node* CodeStubAssembler::SmiSub(Node* a, Node* b) { | |
| 447 return BitcastWordToTaggedSigned( | |
| 448 IntPtrSub(BitcastTaggedToWord(a), BitcastTaggedToWord(b))); | |
| 449 } | |
| 450 | |
| 451 Node* CodeStubAssembler::SmiEqual(Node* a, Node* b) { | |
| 452 return WordEqual(BitcastTaggedToWord(a), BitcastTaggedToWord(b)); | |
| 453 } | |
| 454 | |
| 455 Node* CodeStubAssembler::SmiAbove(Node* a, Node* b) { | |
| 456 return UintPtrGreaterThan(BitcastTaggedToWord(a), BitcastTaggedToWord(b)); | |
| 457 } | |
| 458 | |
| 459 Node* CodeStubAssembler::SmiAboveOrEqual(Node* a, Node* b) { | |
| 460 return UintPtrGreaterThanOrEqual(BitcastTaggedToWord(a), | |
| 461 BitcastTaggedToWord(b)); | |
| 462 } | |
| 463 | |
| 464 Node* CodeStubAssembler::SmiBelow(Node* a, Node* b) { | |
| 465 return UintPtrLessThan(BitcastTaggedToWord(a), BitcastTaggedToWord(b)); | |
| 466 } | |
| 467 | |
| 468 Node* CodeStubAssembler::SmiLessThan(Node* a, Node* b) { | |
| 469 return IntPtrLessThan(BitcastTaggedToWord(a), BitcastTaggedToWord(b)); | |
| 470 } | |
| 471 | |
| 472 Node* CodeStubAssembler::SmiLessThanOrEqual(Node* a, Node* b) { | |
| 473 return IntPtrLessThanOrEqual(BitcastTaggedToWord(a), BitcastTaggedToWord(b)); | |
| 474 } | |
| 475 | |
| 476 Node* CodeStubAssembler::SmiGreaterThan(Node* a, Node* b) { | |
| 477 return IntPtrGreaterThan(BitcastTaggedToWord(a), BitcastTaggedToWord(b)); | |
| 478 } | |
| 479 | |
| 480 Node* CodeStubAssembler::SmiMax(Node* a, Node* b) { | 441 Node* CodeStubAssembler::SmiMax(Node* a, Node* b) { |
| 481 return SelectTaggedConstant(SmiLessThan(a, b), b, a); | 442 return SelectTaggedConstant(SmiLessThan(a, b), b, a); |
| 482 } | 443 } |
| 483 | 444 |
| 484 Node* CodeStubAssembler::SmiMin(Node* a, Node* b) { | 445 Node* CodeStubAssembler::SmiMin(Node* a, Node* b) { |
| 485 return SelectTaggedConstant(SmiLessThan(a, b), a, b); | 446 return SelectTaggedConstant(SmiLessThan(a, b), a, b); |
| 486 } | 447 } |
| 487 | 448 |
| 488 Node* CodeStubAssembler::SmiMod(Node* a, Node* b) { | 449 Node* CodeStubAssembler::SmiMod(Node* a, Node* b) { |
| 489 Variable var_result(this, MachineRepresentation::kTagged); | 450 Variable var_result(this, MachineRepresentation::kTagged); |
| (...skipping 1286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1776 | 1737 |
| 1777 Node* CodeStubAssembler::NewConsString(Node* context, Node* length, Node* left, | 1738 Node* CodeStubAssembler::NewConsString(Node* context, Node* length, Node* left, |
| 1778 Node* right, AllocationFlags flags) { | 1739 Node* right, AllocationFlags flags) { |
| 1779 CSA_ASSERT(this, TaggedIsSmi(length)); | 1740 CSA_ASSERT(this, TaggedIsSmi(length)); |
| 1780 // Added string can be a cons string. | 1741 // Added string can be a cons string. |
| 1781 Comment("Allocating ConsString"); | 1742 Comment("Allocating ConsString"); |
| 1782 Node* left_instance_type = LoadInstanceType(left); | 1743 Node* left_instance_type = LoadInstanceType(left); |
| 1783 Node* right_instance_type = LoadInstanceType(right); | 1744 Node* right_instance_type = LoadInstanceType(right); |
| 1784 | 1745 |
| 1785 // Compute intersection and difference of instance types. | 1746 // Compute intersection and difference of instance types. |
| 1786 Node* anded_instance_types = WordAnd(left_instance_type, right_instance_type); | 1747 Node* anded_instance_types = |
| 1787 Node* xored_instance_types = WordXor(left_instance_type, right_instance_type); | 1748 Word32And(left_instance_type, right_instance_type); |
| 1749 Node* xored_instance_types = |
| 1750 Word32Xor(left_instance_type, right_instance_type); |
| 1788 | 1751 |
| 1789 // We create a one-byte cons string if | 1752 // We create a one-byte cons string if |
| 1790 // 1. both strings are one-byte, or | 1753 // 1. both strings are one-byte, or |
| 1791 // 2. at least one of the strings is two-byte, but happens to contain only | 1754 // 2. at least one of the strings is two-byte, but happens to contain only |
| 1792 // one-byte characters. | 1755 // one-byte characters. |
| 1793 // To do this, we check | 1756 // To do this, we check |
| 1794 // 1. if both strings are one-byte, or if the one-byte data hint is set in | 1757 // 1. if both strings are one-byte, or if the one-byte data hint is set in |
| 1795 // both strings, or | 1758 // both strings, or |
| 1796 // 2. if one of the strings has the one-byte data hint set and the other | 1759 // 2. if one of the strings has the one-byte data hint set and the other |
| 1797 // string is one-byte. | 1760 // string is one-byte. |
| 1798 STATIC_ASSERT(kOneByteStringTag != 0); | 1761 STATIC_ASSERT(kOneByteStringTag != 0); |
| 1799 STATIC_ASSERT(kOneByteDataHintTag != 0); | 1762 STATIC_ASSERT(kOneByteDataHintTag != 0); |
| 1800 Label one_byte_map(this); | 1763 Label one_byte_map(this); |
| 1801 Label two_byte_map(this); | 1764 Label two_byte_map(this); |
| 1802 Variable result(this, MachineRepresentation::kTagged); | 1765 Variable result(this, MachineRepresentation::kTagged); |
| 1803 Label done(this, &result); | 1766 Label done(this, &result); |
| 1804 GotoIf(WordNotEqual( | 1767 GotoIf(Word32NotEqual(Word32And(anded_instance_types, |
| 1805 WordAnd(anded_instance_types, | 1768 Int32Constant(kStringEncodingMask | |
| 1806 IntPtrConstant(kStringEncodingMask | kOneByteDataHintTag)), | 1769 kOneByteDataHintTag)), |
| 1807 IntPtrConstant(0)), | 1770 Int32Constant(0)), |
| 1808 &one_byte_map); | 1771 &one_byte_map); |
| 1809 Branch(WordNotEqual(WordAnd(xored_instance_types, | 1772 Branch(Word32NotEqual(Word32And(xored_instance_types, |
| 1810 IntPtrConstant(kStringEncodingMask | | 1773 Int32Constant(kStringEncodingMask | |
| 1811 kOneByteDataHintMask)), | 1774 kOneByteDataHintMask)), |
| 1812 IntPtrConstant(kOneByteStringTag | kOneByteDataHintTag)), | 1775 Int32Constant(kOneByteStringTag | kOneByteDataHintTag)), |
| 1813 &two_byte_map, &one_byte_map); | 1776 &two_byte_map, &one_byte_map); |
| 1814 | 1777 |
| 1815 Bind(&one_byte_map); | 1778 Bind(&one_byte_map); |
| 1816 Comment("One-byte ConsString"); | 1779 Comment("One-byte ConsString"); |
| 1817 result.Bind(AllocateOneByteConsString(length, left, right, flags)); | 1780 result.Bind(AllocateOneByteConsString(length, left, right, flags)); |
| 1818 Goto(&done); | 1781 Goto(&done); |
| 1819 | 1782 |
| 1820 Bind(&two_byte_map); | 1783 Bind(&two_byte_map); |
| 1821 Comment("Two-byte ConsString"); | 1784 Comment("Two-byte ConsString"); |
| 1822 result.Bind(AllocateTwoByteConsString(length, left, right, flags)); | 1785 result.Bind(AllocateTwoByteConsString(length, left, right, flags)); |
| (...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2354 } else { | 2317 } else { |
| 2355 value = LoadHeapNumberValue(value); | 2318 value = LoadHeapNumberValue(value); |
| 2356 } | 2319 } |
| 2357 } | 2320 } |
| 2358 return value; | 2321 return value; |
| 2359 } | 2322 } |
| 2360 } | 2323 } |
| 2361 | 2324 |
| 2362 Node* CodeStubAssembler::CalculateNewElementsCapacity(Node* old_capacity, | 2325 Node* CodeStubAssembler::CalculateNewElementsCapacity(Node* old_capacity, |
| 2363 ParameterMode mode) { | 2326 ParameterMode mode) { |
| 2327 if (mode == SMI_PARAMETERS) { |
| 2328 old_capacity = BitcastTaggedToWord(old_capacity); |
| 2329 } |
| 2364 Node* half_old_capacity = WordShr(old_capacity, IntPtrConstant(1)); | 2330 Node* half_old_capacity = WordShr(old_capacity, IntPtrConstant(1)); |
| 2365 Node* new_capacity = IntPtrAdd(half_old_capacity, old_capacity); | 2331 Node* new_capacity = IntPtrAdd(half_old_capacity, old_capacity); |
| 2366 Node* unconditioned_result = | 2332 Node* unconditioned_result = IntPtrAdd(new_capacity, IntPtrConstant(16)); |
| 2367 IntPtrAdd(new_capacity, IntPtrOrSmiConstant(16, mode)); | 2333 if (mode == SMI_PARAMETERS) { |
| 2368 if (mode == INTEGER_PARAMETERS || mode == INTPTR_PARAMETERS) { | 2334 return SmiAnd(BitcastWordToTaggedSigned(unconditioned_result), |
| 2335 SmiConstant(-1)); |
| 2336 } else { |
| 2369 return unconditioned_result; | 2337 return unconditioned_result; |
| 2370 } else { | |
| 2371 int const kSmiShiftBits = kSmiShiftSize + kSmiTagSize; | |
| 2372 return WordAnd(unconditioned_result, | |
| 2373 IntPtrConstant(static_cast<size_t>(-1) << kSmiShiftBits)); | |
| 2374 } | 2338 } |
| 2375 } | 2339 } |
| 2376 | 2340 |
| 2377 Node* CodeStubAssembler::TryGrowElementsCapacity(Node* object, Node* elements, | 2341 Node* CodeStubAssembler::TryGrowElementsCapacity(Node* object, Node* elements, |
| 2378 ElementsKind kind, Node* key, | 2342 ElementsKind kind, Node* key, |
| 2379 Label* bailout) { | 2343 Label* bailout) { |
| 2380 Node* capacity = LoadFixedArrayBaseLength(elements); | 2344 Node* capacity = LoadFixedArrayBaseLength(elements); |
| 2381 | 2345 |
| 2382 ParameterMode mode = OptimalParameterMode(); | 2346 ParameterMode mode = OptimalParameterMode(); |
| 2383 capacity = UntagParameter(capacity, mode); | 2347 capacity = UntagParameter(capacity, mode); |
| 2384 key = UntagParameter(key, mode); | 2348 key = UntagParameter(key, mode); |
| 2385 | 2349 |
| 2386 return TryGrowElementsCapacity(object, elements, kind, key, capacity, mode, | 2350 return TryGrowElementsCapacity(object, elements, kind, key, capacity, mode, |
| 2387 bailout); | 2351 bailout); |
| 2388 } | 2352 } |
| 2389 | 2353 |
| 2390 Node* CodeStubAssembler::TryGrowElementsCapacity(Node* object, Node* elements, | 2354 Node* CodeStubAssembler::TryGrowElementsCapacity(Node* object, Node* elements, |
| 2391 ElementsKind kind, Node* key, | 2355 ElementsKind kind, Node* key, |
| 2392 Node* capacity, | 2356 Node* capacity, |
| 2393 ParameterMode mode, | 2357 ParameterMode mode, |
| 2394 Label* bailout) { | 2358 Label* bailout) { |
| 2395 Comment("TryGrowElementsCapacity"); | 2359 Comment("TryGrowElementsCapacity"); |
| 2396 | 2360 |
| 2397 // If the gap growth is too big, fall back to the runtime. | 2361 // If the gap growth is too big, fall back to the runtime. |
| 2398 Node* max_gap = IntPtrOrSmiConstant(JSObject::kMaxGap, mode); | 2362 Node* max_gap = IntPtrOrSmiConstant(JSObject::kMaxGap, mode); |
| 2399 Node* max_capacity = IntPtrAdd(capacity, max_gap); | 2363 Node* max_capacity = IntPtrOrSmiAdd(capacity, max_gap, mode); |
| 2400 GotoIf(UintPtrGreaterThanOrEqual(key, max_capacity), bailout); | 2364 GotoIf(UintPtrOrSmiGreaterThanOrEqual(key, max_capacity, mode), bailout); |
| 2401 | 2365 |
| 2402 // Calculate the capacity of the new backing store. | 2366 // Calculate the capacity of the new backing store. |
| 2403 Node* new_capacity = CalculateNewElementsCapacity( | 2367 Node* new_capacity = CalculateNewElementsCapacity( |
| 2404 IntPtrAdd(key, IntPtrOrSmiConstant(1, mode)), mode); | 2368 IntPtrOrSmiAdd(key, IntPtrOrSmiConstant(1, mode), mode), mode); |
| 2405 return GrowElementsCapacity(object, elements, kind, kind, capacity, | 2369 return GrowElementsCapacity(object, elements, kind, kind, capacity, |
| 2406 new_capacity, mode, bailout); | 2370 new_capacity, mode, bailout); |
| 2407 } | 2371 } |
| 2408 | 2372 |
| 2409 Node* CodeStubAssembler::GrowElementsCapacity( | 2373 Node* CodeStubAssembler::GrowElementsCapacity( |
| 2410 Node* object, Node* elements, ElementsKind from_kind, ElementsKind to_kind, | 2374 Node* object, Node* elements, ElementsKind from_kind, ElementsKind to_kind, |
| 2411 Node* capacity, Node* new_capacity, ParameterMode mode, Label* bailout) { | 2375 Node* capacity, Node* new_capacity, ParameterMode mode, Label* bailout) { |
| 2412 Comment("[ GrowElementsCapacity"); | 2376 Comment("[ GrowElementsCapacity"); |
| 2413 // If size of the allocation for the new capacity doesn't fit in a page | 2377 // If size of the allocation for the new capacity doesn't fit in a page |
| 2414 // that we can bump-pointer allocate from, fall back to the runtime. | 2378 // that we can bump-pointer allocate from, fall back to the runtime. |
| 2415 int max_size = FixedArrayBase::GetMaxLengthForNewSpaceAllocation(to_kind); | 2379 int max_size = FixedArrayBase::GetMaxLengthForNewSpaceAllocation(to_kind); |
| 2416 GotoIf(UintPtrGreaterThanOrEqual(new_capacity, | 2380 GotoIf(UintPtrOrSmiGreaterThanOrEqual( |
| 2417 IntPtrOrSmiConstant(max_size, mode)), | 2381 new_capacity, IntPtrOrSmiConstant(max_size, mode), mode), |
| 2418 bailout); | 2382 bailout); |
| 2419 | 2383 |
| 2420 // Allocate the new backing store. | 2384 // Allocate the new backing store. |
| 2421 Node* new_elements = AllocateFixedArray(to_kind, new_capacity, mode); | 2385 Node* new_elements = AllocateFixedArray(to_kind, new_capacity, mode); |
| 2422 | 2386 |
| 2423 // Copy the elements from the old elements store to the new. | 2387 // Copy the elements from the old elements store to the new. |
| 2424 // The size-check above guarantees that the |new_elements| is allocated | 2388 // The size-check above guarantees that the |new_elements| is allocated |
| 2425 // in new space so we can skip the write barrier. | 2389 // in new space so we can skip the write barrier. |
| 2426 CopyFixedArrayElements(from_kind, elements, to_kind, new_elements, capacity, | 2390 CopyFixedArrayElements(from_kind, elements, to_kind, new_elements, capacity, |
| 2427 new_capacity, SKIP_WRITE_BARRIER, mode); | 2391 new_capacity, SKIP_WRITE_BARRIER, mode); |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2599 Goto(&if_join); | 2563 Goto(&if_join); |
| 2600 } else { | 2564 } else { |
| 2601 Node* pair = Int32AddWithOverflow(value32, value32); | 2565 Node* pair = Int32AddWithOverflow(value32, value32); |
| 2602 Node* overflow = Projection(1, pair); | 2566 Node* overflow = Projection(1, pair); |
| 2603 Label if_overflow(this, Label::kDeferred), if_notoverflow(this); | 2567 Label if_overflow(this, Label::kDeferred), if_notoverflow(this); |
| 2604 Branch(overflow, &if_overflow, &if_notoverflow); | 2568 Branch(overflow, &if_overflow, &if_notoverflow); |
| 2605 Bind(&if_overflow); | 2569 Bind(&if_overflow); |
| 2606 Goto(&if_valueisheapnumber); | 2570 Goto(&if_valueisheapnumber); |
| 2607 Bind(&if_notoverflow); | 2571 Bind(&if_notoverflow); |
| 2608 { | 2572 { |
| 2609 Node* result = Projection(0, pair); | 2573 Node* result = BitcastWordToTaggedSigned(Projection(0, pair)); |
| 2610 var_result.Bind(result); | 2574 var_result.Bind(result); |
| 2611 Goto(&if_join); | 2575 Goto(&if_join); |
| 2612 } | 2576 } |
| 2613 } | 2577 } |
| 2614 } | 2578 } |
| 2615 Bind(&if_valueisheapnumber); | 2579 Bind(&if_valueisheapnumber); |
| 2616 { | 2580 { |
| 2617 Node* result = AllocateHeapNumberWithValue(value); | 2581 Node* result = AllocateHeapNumberWithValue(value); |
| 2618 var_result.Bind(result); | 2582 var_result.Bind(result); |
| 2619 Goto(&if_join); | 2583 Goto(&if_join); |
| (...skipping 882 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3502 Bind(&check_right); | 3466 Bind(&check_right); |
| 3503 Node* right_length = LoadStringLength(right); | 3467 Node* right_length = LoadStringLength(right); |
| 3504 GotoIf(WordNotEqual(IntPtrConstant(0), right_length), &cons); | 3468 GotoIf(WordNotEqual(IntPtrConstant(0), right_length), &cons); |
| 3505 result.Bind(left); | 3469 result.Bind(left); |
| 3506 Goto(&done_native); | 3470 Goto(&done_native); |
| 3507 | 3471 |
| 3508 Bind(&cons); | 3472 Bind(&cons); |
| 3509 CSA_ASSERT(this, TaggedIsSmi(left_length)); | 3473 CSA_ASSERT(this, TaggedIsSmi(left_length)); |
| 3510 CSA_ASSERT(this, TaggedIsSmi(right_length)); | 3474 CSA_ASSERT(this, TaggedIsSmi(right_length)); |
| 3511 Node* new_length = SmiAdd(left_length, right_length); | 3475 Node* new_length = SmiAdd(left_length, right_length); |
| 3512 GotoIf(UintPtrGreaterThanOrEqual( | 3476 GotoIf(SmiAboveOrEqual(new_length, SmiConstant(String::kMaxLength)), |
| 3513 new_length, SmiConstant(Smi::FromInt(String::kMaxLength))), | |
| 3514 &runtime); | 3477 &runtime); |
| 3515 | 3478 |
| 3516 GotoIf(IntPtrLessThan(new_length, | 3479 GotoIf(SmiLessThan(new_length, SmiConstant(ConsString::kMinLength)), |
| 3517 SmiConstant(Smi::FromInt(ConsString::kMinLength))), | |
| 3518 &non_cons); | 3480 &non_cons); |
| 3519 | 3481 |
| 3520 result.Bind(NewConsString(context, new_length, left, right, flags)); | 3482 result.Bind(NewConsString(context, new_length, left, right, flags)); |
| 3521 Goto(&done_native); | 3483 Goto(&done_native); |
| 3522 | 3484 |
| 3523 Bind(&non_cons); | 3485 Bind(&non_cons); |
| 3524 | 3486 |
| 3525 Comment("Full string concatenate"); | 3487 Comment("Full string concatenate"); |
| 3526 Node* left_instance_type = LoadInstanceType(left); | 3488 Node* left_instance_type = LoadInstanceType(left); |
| 3527 Node* right_instance_type = LoadInstanceType(right); | 3489 Node* right_instance_type = LoadInstanceType(right); |
| 3528 // Compute intersection and difference of instance types. | 3490 // Compute intersection and difference of instance types. |
| 3529 | 3491 |
| 3530 Node* ored_instance_types = WordOr(left_instance_type, right_instance_type); | 3492 Node* ored_instance_types = Word32Or(left_instance_type, right_instance_type); |
| 3531 Node* xored_instance_types = WordXor(left_instance_type, right_instance_type); | 3493 Node* xored_instance_types = |
| 3494 Word32Xor(left_instance_type, right_instance_type); |
| 3532 | 3495 |
| 3533 // Check if both strings have the same encoding and both are sequential. | 3496 // Check if both strings have the same encoding and both are sequential. |
| 3534 GotoIf(WordNotEqual( | 3497 GotoIf(Word32NotEqual(Word32And(xored_instance_types, |
| 3535 WordAnd(xored_instance_types, IntPtrConstant(kStringEncodingMask)), | 3498 Int32Constant(kStringEncodingMask)), |
| 3536 IntPtrConstant(0)), | 3499 Int32Constant(0)), |
| 3537 &runtime); | 3500 &runtime); |
| 3538 GotoIf(WordNotEqual(WordAnd(ored_instance_types, | 3501 GotoIf(Word32NotEqual(Word32And(ored_instance_types, |
| 3539 IntPtrConstant(kStringRepresentationMask)), | 3502 Int32Constant(kStringRepresentationMask)), |
| 3540 IntPtrConstant(0)), | 3503 Int32Constant(0)), |
| 3541 &runtime); | 3504 &runtime); |
| 3542 | 3505 |
| 3543 Label two_byte(this); | 3506 Label two_byte(this); |
| 3544 GotoIf(WordEqual( | 3507 GotoIf(Word32Equal( |
| 3545 WordAnd(ored_instance_types, IntPtrConstant(kStringEncodingMask)), | 3508 Word32And(ored_instance_types, Int32Constant(kStringEncodingMask)), |
| 3546 IntPtrConstant(kTwoByteStringTag)), | 3509 Int32Constant(kTwoByteStringTag)), |
| 3547 &two_byte); | 3510 &two_byte); |
| 3548 // One-byte sequential string case | 3511 // One-byte sequential string case |
| 3549 Node* new_string = | 3512 Node* new_string = |
| 3550 AllocateSeqOneByteString(context, new_length, SMI_PARAMETERS); | 3513 AllocateSeqOneByteString(context, new_length, SMI_PARAMETERS); |
| 3551 CopyStringCharacters(left, new_string, SmiConstant(Smi::kZero), | 3514 CopyStringCharacters(left, new_string, SmiConstant(Smi::kZero), |
| 3552 SmiConstant(Smi::kZero), left_length, | 3515 SmiConstant(Smi::kZero), left_length, |
| 3553 String::ONE_BYTE_ENCODING, String::ONE_BYTE_ENCODING, | 3516 String::ONE_BYTE_ENCODING, String::ONE_BYTE_ENCODING, |
| 3554 SMI_PARAMETERS); | 3517 SMI_PARAMETERS); |
| 3555 CopyStringCharacters(right, new_string, SmiConstant(Smi::kZero), left_length, | 3518 CopyStringCharacters(right, new_string, SmiConstant(Smi::kZero), left_length, |
| 3556 right_length, String::ONE_BYTE_ENCODING, | 3519 right_length, String::ONE_BYTE_ENCODING, |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3737 Variable result(this, MachineRepresentation::kTagged); | 3700 Variable result(this, MachineRepresentation::kTagged); |
| 3738 Label runtime(this, Label::kDeferred); | 3701 Label runtime(this, Label::kDeferred); |
| 3739 Label smi(this); | 3702 Label smi(this); |
| 3740 Label done(this, &result); | 3703 Label done(this, &result); |
| 3741 | 3704 |
| 3742 // Load the number string cache. | 3705 // Load the number string cache. |
| 3743 Node* number_string_cache = LoadRoot(Heap::kNumberStringCacheRootIndex); | 3706 Node* number_string_cache = LoadRoot(Heap::kNumberStringCacheRootIndex); |
| 3744 | 3707 |
| 3745 // Make the hash mask from the length of the number string cache. It | 3708 // Make the hash mask from the length of the number string cache. It |
| 3746 // contains two elements (number and string) for each cache entry. | 3709 // contains two elements (number and string) for each cache entry. |
| 3747 Node* mask = LoadFixedArrayBaseLength(number_string_cache); | 3710 // TODO(ishell): cleanup mask handling. |
| 3711 Node* mask = |
| 3712 BitcastTaggedToWord(LoadFixedArrayBaseLength(number_string_cache)); |
| 3748 Node* one = IntPtrConstant(1); | 3713 Node* one = IntPtrConstant(1); |
| 3749 mask = IntPtrSub(mask, one); | 3714 mask = IntPtrSub(mask, one); |
| 3750 | 3715 |
| 3751 GotoIf(TaggedIsSmi(argument), &smi); | 3716 GotoIf(TaggedIsSmi(argument), &smi); |
| 3752 | 3717 |
| 3753 // Argument isn't smi, check to see if it's a heap-number. | 3718 // Argument isn't smi, check to see if it's a heap-number. |
| 3754 Node* map = LoadMap(argument); | 3719 Node* map = LoadMap(argument); |
| 3755 GotoUnless(IsHeapNumberMap(map), &runtime); | 3720 GotoUnless(IsHeapNumberMap(map), &runtime); |
| 3756 | 3721 |
| 3757 // Make a hash from the two 32-bit values of the double. | 3722 // Make a hash from the two 32-bit values of the double. |
| 3758 Node* low = | 3723 Node* low = |
| 3759 LoadObjectField(argument, HeapNumber::kValueOffset, MachineType::Int32()); | 3724 LoadObjectField(argument, HeapNumber::kValueOffset, MachineType::Int32()); |
| 3760 Node* high = LoadObjectField(argument, HeapNumber::kValueOffset + kIntSize, | 3725 Node* high = LoadObjectField(argument, HeapNumber::kValueOffset + kIntSize, |
| 3761 MachineType::Int32()); | 3726 MachineType::Int32()); |
| 3762 Node* hash = Word32Xor(low, high); | 3727 Node* hash = Word32Xor(low, high); |
| 3763 if (Is64()) hash = ChangeInt32ToInt64(hash); | 3728 hash = ChangeInt32ToIntPtr(hash); |
| 3764 hash = WordShl(hash, one); | 3729 hash = WordShl(hash, one); |
| 3765 Node* index = WordAnd(hash, SmiToWord(mask)); | 3730 Node* index = WordAnd(hash, SmiUntag(BitcastWordToTagged(mask))); |
| 3766 | 3731 |
| 3767 // Cache entry's key must be a heap number | 3732 // Cache entry's key must be a heap number |
| 3768 Node* number_key = | 3733 Node* number_key = |
| 3769 LoadFixedArrayElement(number_string_cache, index, 0, INTPTR_PARAMETERS); | 3734 LoadFixedArrayElement(number_string_cache, index, 0, INTPTR_PARAMETERS); |
| 3770 GotoIf(TaggedIsSmi(number_key), &runtime); | 3735 GotoIf(TaggedIsSmi(number_key), &runtime); |
| 3771 map = LoadMap(number_key); | 3736 map = LoadMap(number_key); |
| 3772 GotoUnless(IsHeapNumberMap(map), &runtime); | 3737 GotoUnless(IsHeapNumberMap(map), &runtime); |
| 3773 | 3738 |
| 3774 // Cache entry's key must match the heap number value we're looking for. | 3739 // Cache entry's key must match the heap number value we're looking for. |
| 3775 Node* low_compare = LoadObjectField(number_key, HeapNumber::kValueOffset, | 3740 Node* low_compare = LoadObjectField(number_key, HeapNumber::kValueOffset, |
| 3776 MachineType::Int32()); | 3741 MachineType::Int32()); |
| 3777 Node* high_compare = LoadObjectField( | 3742 Node* high_compare = LoadObjectField( |
| 3778 number_key, HeapNumber::kValueOffset + kIntSize, MachineType::Int32()); | 3743 number_key, HeapNumber::kValueOffset + kIntSize, MachineType::Int32()); |
| 3779 GotoUnless(WordEqual(low, low_compare), &runtime); | 3744 GotoUnless(Word32Equal(low, low_compare), &runtime); |
| 3780 GotoUnless(WordEqual(high, high_compare), &runtime); | 3745 GotoUnless(Word32Equal(high, high_compare), &runtime); |
| 3781 | 3746 |
| 3782 // Heap number match, return value fro cache entry. | 3747 // Heap number match, return value fro cache entry. |
| 3783 IncrementCounter(isolate()->counters()->number_to_string_native(), 1); | 3748 IncrementCounter(isolate()->counters()->number_to_string_native(), 1); |
| 3784 result.Bind(LoadFixedArrayElement(number_string_cache, index, kPointerSize, | 3749 result.Bind(LoadFixedArrayElement(number_string_cache, index, kPointerSize, |
| 3785 INTPTR_PARAMETERS)); | 3750 INTPTR_PARAMETERS)); |
| 3786 Goto(&done); | 3751 Goto(&done); |
| 3787 | 3752 |
| 3788 Bind(&runtime); | 3753 Bind(&runtime); |
| 3789 { | 3754 { |
| 3790 // No cache entry, go to the runtime. | 3755 // No cache entry, go to the runtime. |
| 3791 result.Bind(CallRuntime(Runtime::kNumberToString, context, argument)); | 3756 result.Bind(CallRuntime(Runtime::kNumberToString, context, argument)); |
| 3792 } | 3757 } |
| 3793 Goto(&done); | 3758 Goto(&done); |
| 3794 | 3759 |
| 3795 Bind(&smi); | 3760 Bind(&smi); |
| 3796 { | 3761 { |
| 3797 // Load the smi key, make sure it matches the smi we're looking for. | 3762 // Load the smi key, make sure it matches the smi we're looking for. |
| 3798 Node* smi_index = WordAnd(WordShl(argument, one), mask); | 3763 Node* smi_index = BitcastWordToTagged( |
| 3764 WordAnd(WordShl(BitcastTaggedToWord(argument), one), mask)); |
| 3799 Node* smi_key = LoadFixedArrayElement(number_string_cache, smi_index, 0, | 3765 Node* smi_key = LoadFixedArrayElement(number_string_cache, smi_index, 0, |
| 3800 SMI_PARAMETERS); | 3766 SMI_PARAMETERS); |
| 3801 GotoIf(WordNotEqual(smi_key, argument), &runtime); | 3767 GotoIf(WordNotEqual(smi_key, argument), &runtime); |
| 3802 | 3768 |
| 3803 // Smi match, return value from cache entry. | 3769 // Smi match, return value from cache entry. |
| 3804 IncrementCounter(isolate()->counters()->number_to_string_native(), 1); | 3770 IncrementCounter(isolate()->counters()->number_to_string_native(), 1); |
| 3805 result.Bind(LoadFixedArrayElement(number_string_cache, smi_index, | 3771 result.Bind(LoadFixedArrayElement(number_string_cache, smi_index, |
| 3806 kPointerSize, SMI_PARAMETERS)); | 3772 kPointerSize, SMI_PARAMETERS)); |
| 3807 Goto(&done); | 3773 Goto(&done); |
| 3808 } | 3774 } |
| (...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4592 (NameDictionary::kEntryValueIndex - NameDictionary::kEntryKeyIndex) * | 4558 (NameDictionary::kEntryValueIndex - NameDictionary::kEntryKeyIndex) * |
| 4593 kPointerSize; | 4559 kPointerSize; |
| 4594 StoreFixedArrayElement(dictionary, index, value, UPDATE_WRITE_BARRIER, | 4560 StoreFixedArrayElement(dictionary, index, value, UPDATE_WRITE_BARRIER, |
| 4595 kNameToValueOffset, INTPTR_PARAMETERS); | 4561 kNameToValueOffset, INTPTR_PARAMETERS); |
| 4596 | 4562 |
| 4597 // Prepare details of the new property. | 4563 // Prepare details of the new property. |
| 4598 Variable var_details(this, MachineRepresentation::kTaggedSigned); | 4564 Variable var_details(this, MachineRepresentation::kTaggedSigned); |
| 4599 const int kInitialIndex = 0; | 4565 const int kInitialIndex = 0; |
| 4600 PropertyDetails d(NONE, DATA, kInitialIndex, PropertyCellType::kNoCell); | 4566 PropertyDetails d(NONE, DATA, kInitialIndex, PropertyCellType::kNoCell); |
| 4601 enum_index = | 4567 enum_index = |
| 4602 WordShl(enum_index, PropertyDetails::DictionaryStorageField::kShift); | 4568 SmiShl(enum_index, PropertyDetails::DictionaryStorageField::kShift); |
| 4603 STATIC_ASSERT(kInitialIndex == 0); | 4569 STATIC_ASSERT(kInitialIndex == 0); |
| 4604 var_details.Bind(WordOr(SmiConstant(d.AsSmi()), enum_index)); | 4570 var_details.Bind(SmiOr(SmiConstant(d.AsSmi()), enum_index)); |
| 4605 | 4571 |
| 4606 // Private names must be marked non-enumerable. | 4572 // Private names must be marked non-enumerable. |
| 4607 Label not_private(this, &var_details); | 4573 Label not_private(this, &var_details); |
| 4608 GotoUnless(IsSymbolMap(LoadMap(name)), ¬_private); | 4574 GotoUnless(IsSymbolMap(LoadMap(name)), ¬_private); |
| 4609 Node* flags = SmiToWord32(LoadObjectField(name, Symbol::kFlagsOffset)); | 4575 Node* flags = SmiToWord32(LoadObjectField(name, Symbol::kFlagsOffset)); |
| 4610 const int kPrivateMask = 1 << Symbol::kPrivateBit; | 4576 const int kPrivateMask = 1 << Symbol::kPrivateBit; |
| 4611 GotoUnless(IsSetWord32(flags, kPrivateMask), ¬_private); | 4577 GotoUnless(IsSetWord32(flags, kPrivateMask), ¬_private); |
| 4612 Node* dont_enum = | 4578 Node* dont_enum = |
| 4613 WordShl(SmiConstant(DONT_ENUM), PropertyDetails::AttributesField::kShift); | 4579 SmiShl(SmiConstant(DONT_ENUM), PropertyDetails::AttributesField::kShift); |
| 4614 var_details.Bind(WordOr(var_details.value(), dont_enum)); | 4580 var_details.Bind(SmiOr(var_details.value(), dont_enum)); |
| 4615 Goto(¬_private); | 4581 Goto(¬_private); |
| 4616 Bind(¬_private); | 4582 Bind(¬_private); |
| 4617 | 4583 |
| 4618 // Finally, store the details. | 4584 // Finally, store the details. |
| 4619 const int kNameToDetailsOffset = | 4585 const int kNameToDetailsOffset = |
| 4620 (NameDictionary::kEntryDetailsIndex - NameDictionary::kEntryKeyIndex) * | 4586 (NameDictionary::kEntryDetailsIndex - NameDictionary::kEntryKeyIndex) * |
| 4621 kPointerSize; | 4587 kPointerSize; |
| 4622 StoreFixedArrayElement(dictionary, index, var_details.value(), | 4588 StoreFixedArrayElement(dictionary, index, var_details.value(), |
| 4623 SKIP_WRITE_BARRIER, kNameToDetailsOffset, | 4589 SKIP_WRITE_BARRIER, kNameToDetailsOffset, |
| 4624 INTPTR_PARAMETERS); | 4590 INTPTR_PARAMETERS); |
| 4625 } | 4591 } |
| 4626 | 4592 |
| 4627 template <> | 4593 template <> |
| 4628 void CodeStubAssembler::InsertEntry<GlobalDictionary>(Node* dictionary, | 4594 void CodeStubAssembler::InsertEntry<GlobalDictionary>(Node* dictionary, |
| 4629 Node* key, Node* value, | 4595 Node* key, Node* value, |
| 4630 Node* index, | 4596 Node* index, |
| 4631 Node* enum_index) { | 4597 Node* enum_index) { |
| 4632 UNIMPLEMENTED(); | 4598 UNIMPLEMENTED(); |
| 4633 } | 4599 } |
| 4634 | 4600 |
| 4635 template <class Dictionary> | 4601 template <class Dictionary> |
| 4636 void CodeStubAssembler::Add(Node* dictionary, Node* key, Node* value, | 4602 void CodeStubAssembler::Add(Node* dictionary, Node* key, Node* value, |
| 4637 Label* bailout) { | 4603 Label* bailout) { |
| 4638 Node* capacity = GetCapacity<Dictionary>(dictionary); | 4604 Node* capacity = GetCapacity<Dictionary>(dictionary); |
| 4639 Node* nof = GetNumberOfElements<Dictionary>(dictionary); | 4605 Node* nof = GetNumberOfElements<Dictionary>(dictionary); |
| 4640 Node* new_nof = SmiAdd(nof, SmiConstant(1)); | 4606 Node* new_nof = SmiAdd(nof, SmiConstant(1)); |
| 4641 // Require 33% to still be free after adding additional_elements. | 4607 // Require 33% to still be free after adding additional_elements. |
| 4642 // Computing "x + (x >> 1)" on a Smi x does not return a valid Smi! | 4608 // Computing "x + (x >> 1)" on a Smi x does not return a valid Smi! |
| 4643 // But that's OK here because it's only used for a comparison. | 4609 // But that's OK here because it's only used for a comparison. |
| 4644 Node* required_capacity_pseudo_smi = SmiAdd(new_nof, WordShr(new_nof, 1)); | 4610 Node* required_capacity_pseudo_smi = SmiAdd(new_nof, SmiShr(new_nof, 1)); |
| 4645 GotoIf(UintPtrLessThan(capacity, required_capacity_pseudo_smi), bailout); | 4611 GotoIf(SmiBelow(capacity, required_capacity_pseudo_smi), bailout); |
| 4646 // Require rehashing if more than 50% of free elements are deleted elements. | 4612 // Require rehashing if more than 50% of free elements are deleted elements. |
| 4647 Node* deleted = GetNumberOfDeletedElements<Dictionary>(dictionary); | 4613 Node* deleted = GetNumberOfDeletedElements<Dictionary>(dictionary); |
| 4648 CSA_ASSERT(this, UintPtrGreaterThan(capacity, new_nof)); | 4614 CSA_ASSERT(this, SmiAbove(capacity, new_nof)); |
| 4649 Node* half_of_free_elements = WordShr(SmiSub(capacity, new_nof), 1); | 4615 Node* half_of_free_elements = SmiShr(SmiSub(capacity, new_nof), 1); |
| 4650 GotoIf(UintPtrGreaterThan(deleted, half_of_free_elements), bailout); | 4616 GotoIf(SmiAbove(deleted, half_of_free_elements), bailout); |
| 4651 Node* enum_index = nullptr; | 4617 Node* enum_index = nullptr; |
| 4652 if (Dictionary::kIsEnumerable) { | 4618 if (Dictionary::kIsEnumerable) { |
| 4653 enum_index = GetNextEnumerationIndex<Dictionary>(dictionary); | 4619 enum_index = GetNextEnumerationIndex<Dictionary>(dictionary); |
| 4654 Node* new_enum_index = SmiAdd(enum_index, SmiConstant(1)); | 4620 Node* new_enum_index = SmiAdd(enum_index, SmiConstant(1)); |
| 4655 Node* max_enum_index = | 4621 Node* max_enum_index = |
| 4656 SmiConstant(PropertyDetails::DictionaryStorageField::kMax); | 4622 SmiConstant(PropertyDetails::DictionaryStorageField::kMax); |
| 4657 GotoIf(UintPtrGreaterThan(new_enum_index, max_enum_index), bailout); | 4623 GotoIf(SmiAbove(new_enum_index, max_enum_index), bailout); |
| 4658 | 4624 |
| 4659 // No more bailouts after this point. | 4625 // No more bailouts after this point. |
| 4660 // Operations from here on can have side effects. | 4626 // Operations from here on can have side effects. |
| 4661 | 4627 |
| 4662 SetNextEnumerationIndex<Dictionary>(dictionary, new_enum_index); | 4628 SetNextEnumerationIndex<Dictionary>(dictionary, new_enum_index); |
| 4663 } else { | 4629 } else { |
| 4664 USE(enum_index); | 4630 USE(enum_index); |
| 4665 } | 4631 } |
| 4666 SetNumberOfElements<Dictionary>(dictionary, new_nof); | 4632 SetNumberOfElements<Dictionary>(dictionary, new_nof); |
| 4667 | 4633 |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4799 DCHECK_EQ(MachineRepresentation::kTagged, var_value->rep()); | 4765 DCHECK_EQ(MachineRepresentation::kTagged, var_value->rep()); |
| 4800 Comment("[ LoadPropertyFromFastObject"); | 4766 Comment("[ LoadPropertyFromFastObject"); |
| 4801 | 4767 |
| 4802 const int name_to_details_offset = | 4768 const int name_to_details_offset = |
| 4803 (DescriptorArray::kDescriptorDetails - DescriptorArray::kDescriptorKey) * | 4769 (DescriptorArray::kDescriptorDetails - DescriptorArray::kDescriptorKey) * |
| 4804 kPointerSize; | 4770 kPointerSize; |
| 4805 const int name_to_value_offset = | 4771 const int name_to_value_offset = |
| 4806 (DescriptorArray::kDescriptorValue - DescriptorArray::kDescriptorKey) * | 4772 (DescriptorArray::kDescriptorValue - DescriptorArray::kDescriptorKey) * |
| 4807 kPointerSize; | 4773 kPointerSize; |
| 4808 | 4774 |
| 4809 Node* details = LoadAndUntagToWord32FixedArrayElement(descriptors, name_index, | 4775 Node* details = LoadAndUntagToWord32FixedArrayElement( |
| 4810 name_to_details_offset); | 4776 descriptors, name_index, name_to_details_offset, INTPTR_PARAMETERS); |
| 4811 var_details->Bind(details); | 4777 var_details->Bind(details); |
| 4812 | 4778 |
| 4813 Node* location = DecodeWord32<PropertyDetails::LocationField>(details); | 4779 Node* location = DecodeWord32<PropertyDetails::LocationField>(details); |
| 4814 | 4780 |
| 4815 Label if_in_field(this), if_in_descriptor(this), done(this); | 4781 Label if_in_field(this), if_in_descriptor(this), done(this); |
| 4816 Branch(Word32Equal(location, Int32Constant(kField)), &if_in_field, | 4782 Branch(Word32Equal(location, Int32Constant(kField)), &if_in_field, |
| 4817 &if_in_descriptor); | 4783 &if_in_descriptor); |
| 4818 Bind(&if_in_field); | 4784 Bind(&if_in_field); |
| 4819 { | 4785 { |
| 4820 Node* field_index = | 4786 Node* field_index = |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4884 Bind(&rebox_double); | 4850 Bind(&rebox_double); |
| 4885 { | 4851 { |
| 4886 Comment("rebox_double"); | 4852 Comment("rebox_double"); |
| 4887 Node* heap_number = AllocateHeapNumberWithValue(var_double_value.value()); | 4853 Node* heap_number = AllocateHeapNumberWithValue(var_double_value.value()); |
| 4888 var_value->Bind(heap_number); | 4854 var_value->Bind(heap_number); |
| 4889 Goto(&done); | 4855 Goto(&done); |
| 4890 } | 4856 } |
| 4891 } | 4857 } |
| 4892 Bind(&if_in_descriptor); | 4858 Bind(&if_in_descriptor); |
| 4893 { | 4859 { |
| 4894 Node* value = | 4860 Node* value = LoadFixedArrayElement( |
| 4895 LoadFixedArrayElement(descriptors, name_index, name_to_value_offset); | 4861 descriptors, name_index, name_to_value_offset, INTPTR_PARAMETERS); |
| 4896 var_value->Bind(value); | 4862 var_value->Bind(value); |
| 4897 Goto(&done); | 4863 Goto(&done); |
| 4898 } | 4864 } |
| 4899 Bind(&done); | 4865 Bind(&done); |
| 4900 | 4866 |
| 4901 Comment("] LoadPropertyFromFastObject"); | 4867 Comment("] LoadPropertyFromFastObject"); |
| 4902 } | 4868 } |
| 4903 | 4869 |
| 4904 void CodeStubAssembler::LoadPropertyFromNameDictionary(Node* dictionary, | 4870 void CodeStubAssembler::LoadPropertyFromNameDictionary(Node* dictionary, |
| 4905 Node* name_index, | 4871 Node* name_index, |
| 4906 Variable* var_details, | 4872 Variable* var_details, |
| 4907 Variable* var_value) { | 4873 Variable* var_value) { |
| 4908 Comment("LoadPropertyFromNameDictionary"); | 4874 Comment("LoadPropertyFromNameDictionary"); |
| 4909 CSA_ASSERT(this, IsDictionary(dictionary)); | 4875 CSA_ASSERT(this, IsDictionary(dictionary)); |
| 4910 const int name_to_details_offset = | 4876 const int name_to_details_offset = |
| 4911 (NameDictionary::kEntryDetailsIndex - NameDictionary::kEntryKeyIndex) * | 4877 (NameDictionary::kEntryDetailsIndex - NameDictionary::kEntryKeyIndex) * |
| 4912 kPointerSize; | 4878 kPointerSize; |
| 4913 const int name_to_value_offset = | 4879 const int name_to_value_offset = |
| 4914 (NameDictionary::kEntryValueIndex - NameDictionary::kEntryKeyIndex) * | 4880 (NameDictionary::kEntryValueIndex - NameDictionary::kEntryKeyIndex) * |
| 4915 kPointerSize; | 4881 kPointerSize; |
| 4916 | 4882 |
| 4917 Node* details = LoadAndUntagToWord32FixedArrayElement(dictionary, name_index, | 4883 Node* details = LoadAndUntagToWord32FixedArrayElement( |
| 4918 name_to_details_offset); | 4884 dictionary, name_index, name_to_details_offset, INTPTR_PARAMETERS); |
| 4919 | 4885 |
| 4920 var_details->Bind(details); | 4886 var_details->Bind(details); |
| 4921 var_value->Bind(LoadFixedArrayElement( | 4887 var_value->Bind(LoadFixedArrayElement( |
| 4922 dictionary, name_index, name_to_value_offset, INTPTR_PARAMETERS)); | 4888 dictionary, name_index, name_to_value_offset, INTPTR_PARAMETERS)); |
| 4923 | 4889 |
| 4924 Comment("] LoadPropertyFromNameDictionary"); | 4890 Comment("] LoadPropertyFromNameDictionary"); |
| 4925 } | 4891 } |
| 4926 | 4892 |
| 4927 void CodeStubAssembler::LoadPropertyFromGlobalDictionary(Node* dictionary, | 4893 void CodeStubAssembler::LoadPropertyFromGlobalDictionary(Node* dictionary, |
| 4928 Node* name_index, | 4894 Node* name_index, |
| (...skipping 1152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6081 Label no_memento_found(this); | 6047 Label no_memento_found(this); |
| 6082 Label top_check(this), map_check(this); | 6048 Label top_check(this), map_check(this); |
| 6083 | 6049 |
| 6084 Node* new_space_top_address = ExternalConstant( | 6050 Node* new_space_top_address = ExternalConstant( |
| 6085 ExternalReference::new_space_allocation_top_address(isolate())); | 6051 ExternalReference::new_space_allocation_top_address(isolate())); |
| 6086 const int kMementoMapOffset = JSArray::kSize; | 6052 const int kMementoMapOffset = JSArray::kSize; |
| 6087 const int kMementoLastWordOffset = | 6053 const int kMementoLastWordOffset = |
| 6088 kMementoMapOffset + AllocationMemento::kSize - kPointerSize; | 6054 kMementoMapOffset + AllocationMemento::kSize - kPointerSize; |
| 6089 | 6055 |
| 6090 // Bail out if the object is not in new space. | 6056 // Bail out if the object is not in new space. |
| 6091 Node* object_page = PageFromAddress(object); | 6057 Node* object_word = BitcastTaggedToWord(object); |
| 6058 Node* object_page = PageFromAddress(object_word); |
| 6092 { | 6059 { |
| 6093 Node* page_flags = Load(MachineType::IntPtr(), object_page, | 6060 Node* page_flags = Load(MachineType::IntPtr(), object_page, |
| 6094 IntPtrConstant(Page::kFlagsOffset)); | 6061 IntPtrConstant(Page::kFlagsOffset)); |
| 6095 GotoIf(WordEqual(WordAnd(page_flags, | 6062 GotoIf(WordEqual(WordAnd(page_flags, |
| 6096 IntPtrConstant(MemoryChunk::kIsInNewSpaceMask)), | 6063 IntPtrConstant(MemoryChunk::kIsInNewSpaceMask)), |
| 6097 IntPtrConstant(0)), | 6064 IntPtrConstant(0)), |
| 6098 &no_memento_found); | 6065 &no_memento_found); |
| 6099 } | 6066 } |
| 6100 | 6067 |
| 6101 Node* memento_last_word = IntPtrAdd( | 6068 Node* memento_last_word = IntPtrAdd( |
| 6102 object, IntPtrConstant(kMementoLastWordOffset - kHeapObjectTag)); | 6069 object_word, IntPtrConstant(kMementoLastWordOffset - kHeapObjectTag)); |
| 6103 Node* memento_last_word_page = PageFromAddress(memento_last_word); | 6070 Node* memento_last_word_page = PageFromAddress(memento_last_word); |
| 6104 | 6071 |
| 6105 Node* new_space_top = Load(MachineType::Pointer(), new_space_top_address); | 6072 Node* new_space_top = Load(MachineType::Pointer(), new_space_top_address); |
| 6106 Node* new_space_top_page = PageFromAddress(new_space_top); | 6073 Node* new_space_top_page = PageFromAddress(new_space_top); |
| 6107 | 6074 |
| 6108 // If the object is in new space, we need to check whether respective | 6075 // If the object is in new space, we need to check whether respective |
| 6109 // potential memento object is on the same page as the current top. | 6076 // potential memento object is on the same page as the current top. |
| 6110 GotoIf(WordEqual(memento_last_word_page, new_space_top_page), &top_check); | 6077 GotoIf(WordEqual(memento_last_word_page, new_space_top_page), &top_check); |
| 6111 | 6078 |
| 6112 // The object is on a different page than allocation top. Bail out if the | 6079 // The object is on a different page than allocation top. Bail out if the |
| (...skipping 2126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8239 | 8206 |
| 8240 Node* CodeStubAssembler::IsDebugActive() { | 8207 Node* CodeStubAssembler::IsDebugActive() { |
| 8241 Node* is_debug_active = Load( | 8208 Node* is_debug_active = Load( |
| 8242 MachineType::Uint8(), | 8209 MachineType::Uint8(), |
| 8243 ExternalConstant(ExternalReference::debug_is_active_address(isolate()))); | 8210 ExternalConstant(ExternalReference::debug_is_active_address(isolate()))); |
| 8244 return WordNotEqual(is_debug_active, Int32Constant(0)); | 8211 return WordNotEqual(is_debug_active, Int32Constant(0)); |
| 8245 } | 8212 } |
| 8246 | 8213 |
| 8247 } // namespace internal | 8214 } // namespace internal |
| 8248 } // namespace v8 | 8215 } // namespace v8 |
| OLD | NEW |