LCOV - code coverage report
Current view: top level - test/cctest - test-code-stub-assembler.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 1687 1700 99.2 %
Date: 2019-04-17 Functions: 101 103 98.1 %

          Line data    Source code
       1             : // Copyright 2015 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include <cmath>
       6             : 
       7             : #include "src/api-inl.h"
       8             : #include "src/base/utils/random-number-generator.h"
       9             : #include "src/builtins/builtins-promise-gen.h"
      10             : #include "src/builtins/builtins-promise.h"
      11             : #include "src/builtins/builtins-string-gen.h"
      12             : #include "src/char-predicates.h"
      13             : #include "src/code-factory.h"
      14             : #include "src/code-stub-assembler.h"
      15             : #include "src/compiler/node.h"
      16             : #include "src/debug/debug.h"
      17             : #include "src/hash-seed-inl.h"
      18             : #include "src/heap/heap-inl.h"
      19             : #include "src/isolate.h"
      20             : #include "src/objects-inl.h"
      21             : #include "src/objects/hash-table-inl.h"
      22             : #include "src/objects/heap-number-inl.h"
      23             : #include "src/objects/js-array-buffer-inl.h"
      24             : #include "src/objects/js-array-inl.h"
      25             : #include "src/objects/ordered-hash-table-inl.h"
      26             : #include "src/objects/promise-inl.h"
      27             : #include "src/objects/smi.h"
      28             : #include "src/objects/struct-inl.h"
      29             : #include "src/transitions-inl.h"
      30             : #include "test/cctest/compiler/code-assembler-tester.h"
      31             : #include "test/cctest/compiler/function-tester.h"
      32             : 
      33             : namespace v8 {
      34             : namespace internal {
      35             : namespace compiler {
      36             : 
      37             : namespace {
      38             : 
      39             : using Label = CodeAssemblerLabel;
      40             : using Variable = CodeAssemblerVariable;
      41             : template <class T>
      42             : using TVariable = TypedCodeAssemblerVariable<T>;
      43             : 
      44             : Handle<String> MakeString(const char* str) {
      45             :   Isolate* isolate = CcTest::i_isolate();
      46             :   Factory* factory = isolate->factory();
      47        1096 :   return factory->InternalizeUtf8String(str);
      48             : }
      49             : 
      50        1080 : Handle<String> MakeName(const char* str, int suffix) {
      51             :   EmbeddedVector<char, 128> buffer;
      52        1080 :   SNPrintF(buffer, "%s%d", str, suffix);
      53        1080 :   return MakeString(buffer.start());
      54             : }
      55             : 
      56           4 : int sum9(int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
      57             :          int a8) {
      58           4 :   return a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8;
      59             : }
      60             : 
      61           4 : static int sum3(int a0, int a1, int a2) { return a0 + a1 + a2; }
      62             : 
      63             : }  // namespace
      64             : 
      65       26643 : TEST(CallCFunction) {
      66             :   Isolate* isolate(CcTest::InitIsolateOnce());
      67             : 
      68             :   const int kNumParams = 0;
      69           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
      70           4 :   CodeStubAssembler m(asm_tester.state());
      71             : 
      72             :   {
      73           8 :     Node* const fun_constant = m.ExternalConstant(
      74           4 :         ExternalReference::Create(reinterpret_cast<Address>(sum9)));
      75             : 
      76             :     MachineType type_intptr = MachineType::IntPtr();
      77             : 
      78             :     Node* const result =
      79             :         m.CallCFunction(fun_constant, type_intptr,
      80           8 :                         std::make_pair(type_intptr, m.IntPtrConstant(0)),
      81           8 :                         std::make_pair(type_intptr, m.IntPtrConstant(1)),
      82           8 :                         std::make_pair(type_intptr, m.IntPtrConstant(2)),
      83           8 :                         std::make_pair(type_intptr, m.IntPtrConstant(3)),
      84           8 :                         std::make_pair(type_intptr, m.IntPtrConstant(4)),
      85           8 :                         std::make_pair(type_intptr, m.IntPtrConstant(5)),
      86           8 :                         std::make_pair(type_intptr, m.IntPtrConstant(6)),
      87           8 :                         std::make_pair(type_intptr, m.IntPtrConstant(7)),
      88          12 :                         std::make_pair(type_intptr, m.IntPtrConstant(8)));
      89           8 :     m.Return(m.SmiTag(result));
      90             :   }
      91             : 
      92           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
      93             : 
      94           8 :   Handle<Object> result = ft.Call().ToHandleChecked();
      95           4 :   CHECK_EQ(36, Handle<Smi>::cast(result)->value());
      96           4 : }
      97             : 
      98       26643 : TEST(CallCFunctionWithCallerSavedRegisters) {
      99             :   Isolate* isolate(CcTest::InitIsolateOnce());
     100             : 
     101             :   const int kNumParams = 0;
     102           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
     103           4 :   CodeStubAssembler m(asm_tester.state());
     104             : 
     105             :   {
     106           8 :     Node* const fun_constant = m.ExternalConstant(
     107           4 :         ExternalReference::Create(reinterpret_cast<Address>(sum3)));
     108             : 
     109             :     MachineType type_intptr = MachineType::IntPtr();
     110             : 
     111             :     Node* const result = m.CallCFunctionWithCallerSavedRegisters(
     112             :         fun_constant, type_intptr, kSaveFPRegs,
     113           8 :         std::make_pair(type_intptr, m.IntPtrConstant(0)),
     114           8 :         std::make_pair(type_intptr, m.IntPtrConstant(1)),
     115           8 :         std::make_pair(type_intptr, m.IntPtrConstant(2)));
     116           8 :     m.Return(m.SmiTag(result));
     117             :   }
     118             : 
     119           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
     120             : 
     121           8 :   Handle<Object> result = ft.Call().ToHandleChecked();
     122           4 :   CHECK_EQ(3, Handle<Smi>::cast(result)->value());
     123           4 : }
     124             : 
     125             : namespace {
     126             : 
     127         164 : void CheckToUint32Result(uint32_t expected, Handle<Object> result) {
     128             :   const int64_t result_int64 = NumberToInt64(*result);
     129         164 :   const uint32_t result_uint32 = NumberToUint32(*result);
     130             : 
     131         164 :   CHECK_EQ(static_cast<int64_t>(result_uint32), result_int64);
     132         164 :   CHECK_EQ(expected, result_uint32);
     133             : 
     134             :   // Ensure that the result is normalized to a Smi, i.e. a HeapNumber is only
     135             :   // returned if the result is not within Smi range.
     136             :   const bool expected_fits_into_intptr =
     137             :       static_cast<int64_t>(expected) <=
     138             :       static_cast<int64_t>(std::numeric_limits<intptr_t>::max());
     139         164 :   if (expected_fits_into_intptr &&
     140         164 :       Smi::IsValid(static_cast<intptr_t>(expected))) {
     141         128 :     CHECK(result->IsSmi());
     142             :   } else {
     143          36 :     CHECK(result->IsHeapNumber());
     144             :   }
     145         164 : }
     146             : 
     147             : }  // namespace
     148             : 
     149       26643 : TEST(ToUint32) {
     150             :   Isolate* isolate(CcTest::InitIsolateOnce());
     151             :   Factory* factory = isolate->factory();
     152             : 
     153             :   const int kNumParams = 1;
     154           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
     155           4 :   CodeStubAssembler m(asm_tester.state());
     156             : 
     157             :   const int kContextOffset = 2;
     158           4 :   Node* const context = m.Parameter(kNumParams + kContextOffset);
     159           4 :   Node* const input = m.Parameter(0);
     160           8 :   m.Return(m.ToUint32(context, input));
     161             : 
     162           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
     163             : 
     164             :   // clang-format off
     165             :   double inputs[] = {
     166             :      std::nan("-1"), std::nan("1"), std::nan("2"),
     167             :     -std::numeric_limits<double>::infinity(),
     168             :      std::numeric_limits<double>::infinity(),
     169             :     -0.0, -0.001, -0.5, -0.999, -1.0,
     170             :      0.0,  0.001,  0.5,  0.999,  1.0,
     171             :     -2147483647.9, -2147483648.0, -2147483648.5, -2147483648.9,  // SmiMin.
     172             :      2147483646.9,  2147483647.0,  2147483647.5,  2147483647.9,  // SmiMax.
     173             :     -4294967295.9, -4294967296.0, -4294967296.5, -4294967297.0,  // - 2^32.
     174             :      4294967295.9,  4294967296.0,  4294967296.5,  4294967297.0,  //   2^32.
     175           4 :   };
     176             : 
     177             :   uint32_t expectations[] = {
     178             :      0, 0, 0,
     179             :      0,
     180             :      0,
     181             :      0, 0, 0, 0, 4294967295,
     182             :      0, 0, 0, 0, 1,
     183             :      2147483649, 2147483648, 2147483648, 2147483648,
     184             :      2147483646, 2147483647, 2147483647, 2147483647,
     185             :      1, 0, 0, 4294967295,
     186             :      4294967295, 0, 0, 1,
     187           4 :   };
     188             :   // clang-format on
     189             : 
     190             :   STATIC_ASSERT(arraysize(inputs) == arraysize(expectations));
     191             : 
     192             :   const int test_count = arraysize(inputs);
     193         252 :   for (int i = 0; i < test_count; i++) {
     194         124 :     Handle<Object> input_obj = factory->NewNumber(inputs[i]);
     195             :     Handle<HeapNumber> input_num;
     196             : 
     197             :     // Check with Smi input.
     198         124 :     if (input_obj->IsSmi()) {
     199          20 :       Handle<Smi> input_smi = Handle<Smi>::cast(input_obj);
     200          40 :       Handle<Object> result = ft.Call(input_smi).ToHandleChecked();
     201          20 :       CheckToUint32Result(expectations[i], result);
     202          20 :       input_num = factory->NewHeapNumber(inputs[i]);
     203             :     } else {
     204             :       input_num = Handle<HeapNumber>::cast(input_obj);
     205             :     }
     206             : 
     207             :     // Check with HeapNumber input.
     208             :     {
     209         124 :       CHECK(input_num->IsHeapNumber());
     210         248 :       Handle<Object> result = ft.Call(input_num).ToHandleChecked();
     211         124 :       CheckToUint32Result(expectations[i], result);
     212             :     }
     213             :   }
     214             : 
     215             :   // A couple of final cases for ToNumber conversions.
     216           8 :   CheckToUint32Result(0, ft.Call(factory->undefined_value()).ToHandleChecked());
     217           8 :   CheckToUint32Result(0, ft.Call(factory->null_value()).ToHandleChecked());
     218           8 :   CheckToUint32Result(0, ft.Call(factory->false_value()).ToHandleChecked());
     219           8 :   CheckToUint32Result(1, ft.Call(factory->true_value()).ToHandleChecked());
     220             :   CheckToUint32Result(
     221             :       42,
     222           8 :       ft.Call(factory->NewStringFromAsciiChecked("0x2A")).ToHandleChecked());
     223             : 
     224           4 :   ft.CheckThrows(factory->match_symbol());
     225           4 : }
     226             : 
     227             : namespace {
     228          44 : void IsValidPositiveSmiCase(Isolate* isolate, intptr_t value) {
     229             :   const int kNumParams = 0;
     230          88 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
     231             : 
     232          44 :   CodeStubAssembler m(asm_tester.state());
     233          44 :   m.Return(
     234         176 :       m.SelectBooleanConstant(m.IsValidPositiveSmi(m.IntPtrConstant(value))));
     235             : 
     236          44 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
     237          44 :   MaybeHandle<Object> maybe_handle = ft.Call();
     238             : 
     239          44 :   bool expected = i::PlatformSmiTagging::IsValidSmi(value) && (value >= 0);
     240          44 :   if (expected) {
     241          20 :     CHECK(maybe_handle.ToHandleChecked()->IsTrue(isolate));
     242             :   } else {
     243          24 :     CHECK(maybe_handle.ToHandleChecked()->IsFalse(isolate));
     244             :   }
     245          44 : }
     246             : }  // namespace
     247             : 
     248       26643 : TEST(IsValidPositiveSmi) {
     249             :   Isolate* isolate(CcTest::InitIsolateOnce());
     250             : 
     251           4 :   IsValidPositiveSmiCase(isolate, -1);
     252           4 :   IsValidPositiveSmiCase(isolate, 0);
     253           4 :   IsValidPositiveSmiCase(isolate, 1);
     254             : 
     255           4 :   IsValidPositiveSmiCase(isolate, 0x3FFFFFFFU);
     256           4 :   IsValidPositiveSmiCase(isolate, 0xC0000000U);
     257           4 :   IsValidPositiveSmiCase(isolate, 0x40000000U);
     258           4 :   IsValidPositiveSmiCase(isolate, 0xBFFFFFFFU);
     259             : 
     260             :   typedef std::numeric_limits<int32_t> int32_limits;
     261           4 :   IsValidPositiveSmiCase(isolate, int32_limits::max());
     262           4 :   IsValidPositiveSmiCase(isolate, int32_limits::min());
     263             : #if V8_TARGET_ARCH_64_BIT
     264             :   IsValidPositiveSmiCase(isolate,
     265           4 :                          static_cast<intptr_t>(int32_limits::max()) + 1);
     266             :   IsValidPositiveSmiCase(isolate,
     267           4 :                          static_cast<intptr_t>(int32_limits::min()) - 1);
     268             : #endif
     269           4 : }
     270             : 
     271       26643 : TEST(FixedArrayAccessSmiIndex) {
     272             :   Isolate* isolate(CcTest::InitIsolateOnce());
     273           8 :   CodeAssemblerTester asm_tester(isolate);
     274           4 :   CodeStubAssembler m(asm_tester.state());
     275           4 :   Handle<FixedArray> array = isolate->factory()->NewFixedArray(5);
     276             :   array->set(4, Smi::FromInt(733));
     277           8 :   m.Return(m.LoadFixedArrayElement(m.HeapConstant(array),
     278          12 :                                    m.SmiTag(m.IntPtrConstant(4)), 0,
     279           4 :                                    CodeStubAssembler::SMI_PARAMETERS));
     280           4 :   FunctionTester ft(asm_tester.GenerateCode());
     281           4 :   MaybeHandle<Object> result = ft.Call();
     282           4 :   CHECK_EQ(733, Handle<Smi>::cast(result.ToHandleChecked())->value());
     283           4 : }
     284             : 
     285       26643 : TEST(LoadHeapNumberValue) {
     286             :   Isolate* isolate(CcTest::InitIsolateOnce());
     287           8 :   CodeAssemblerTester asm_tester(isolate);
     288           4 :   CodeStubAssembler m(asm_tester.state());
     289           4 :   Handle<HeapNumber> number = isolate->factory()->NewHeapNumber(1234);
     290           8 :   m.Return(m.SmiFromInt32(m.Signed(
     291          16 :       m.ChangeFloat64ToUint32(m.LoadHeapNumberValue(m.HeapConstant(number))))));
     292           4 :   FunctionTester ft(asm_tester.GenerateCode());
     293           4 :   MaybeHandle<Object> result = ft.Call();
     294           4 :   CHECK_EQ(1234, Handle<Smi>::cast(result.ToHandleChecked())->value());
     295           4 : }
     296             : 
     297       26643 : TEST(LoadInstanceType) {
     298             :   Isolate* isolate(CcTest::InitIsolateOnce());
     299           8 :   CodeAssemblerTester asm_tester(isolate);
     300           4 :   CodeStubAssembler m(asm_tester.state());
     301             :   Handle<HeapObject> undefined = isolate->factory()->undefined_value();
     302          12 :   m.Return(m.SmiFromInt32(m.LoadInstanceType(m.HeapConstant(undefined))));
     303           4 :   FunctionTester ft(asm_tester.GenerateCode());
     304           4 :   MaybeHandle<Object> result = ft.Call();
     305           4 :   CHECK_EQ(InstanceType::ODDBALL_TYPE,
     306             :            Handle<Smi>::cast(result.ToHandleChecked())->value());
     307           4 : }
     308             : 
     309       26643 : TEST(DecodeWordFromWord32) {
     310             :   Isolate* isolate(CcTest::InitIsolateOnce());
     311           8 :   CodeAssemblerTester asm_tester(isolate);
     312           4 :   CodeStubAssembler m(asm_tester.state());
     313             : 
     314             :   class TestBitField : public BitField<unsigned, 3, 3> {};
     315           8 :   m.Return(m.SmiTag(
     316          16 :       m.Signed(m.DecodeWordFromWord32<TestBitField>(m.Int32Constant(0x2F)))));
     317           4 :   FunctionTester ft(asm_tester.GenerateCode());
     318           4 :   MaybeHandle<Object> result = ft.Call();
     319             :   // value  = 00101111
     320             :   // mask   = 00111000
     321             :   // result = 101
     322           4 :   CHECK_EQ(5, Handle<Smi>::cast(result.ToHandleChecked())->value());
     323           4 : }
     324             : 
     325       26643 : TEST(JSFunction) {
     326             :   const int kNumParams = 3;  // Receiver, left, right.
     327             :   Isolate* isolate(CcTest::InitIsolateOnce());
     328           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
     329           4 :   CodeStubAssembler m(asm_tester.state());
     330           8 :   m.Return(m.SmiFromInt32(
     331          20 :       m.Int32Add(m.SmiToInt32(m.Parameter(1)), m.SmiToInt32(m.Parameter(2)))));
     332             : 
     333           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
     334             : 
     335             :   MaybeHandle<Object> result = ft.Call(isolate->factory()->undefined_value(),
     336             :                                        handle(Smi::FromInt(23), isolate),
     337           4 :                                        handle(Smi::FromInt(34), isolate));
     338           4 :   CHECK_EQ(57, Handle<Smi>::cast(result.ToHandleChecked())->value());
     339           4 : }
     340             : 
     341       26643 : TEST(ComputeIntegerHash) {
     342             :   Isolate* isolate(CcTest::InitIsolateOnce());
     343             :   const int kNumParams = 1;
     344           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
     345           4 :   CodeStubAssembler m(asm_tester.state());
     346             : 
     347          20 :   m.Return(m.SmiFromInt32(m.ComputeSeededHash(m.SmiUntag(m.Parameter(0)))));
     348             : 
     349           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
     350             : 
     351           4 :   base::RandomNumberGenerator rand_gen(FLAG_random_seed);
     352             : 
     353        8196 :   for (int i = 0; i < 1024; i++) {
     354        4096 :     int k = rand_gen.NextInt(Smi::kMaxValue);
     355             : 
     356             :     Handle<Smi> key(Smi::FromInt(k), isolate);
     357        8192 :     Handle<Object> result = ft.Call(key).ToHandleChecked();
     358             : 
     359        4096 :     uint32_t hash = ComputeSeededHash(k, HashSeed(isolate));
     360        4096 :     Smi expected = Smi::FromInt(hash);
     361        4096 :     CHECK_EQ(expected, Smi::cast(*result));
     362             :   }
     363           4 : }
     364             : 
     365       26643 : TEST(ToString) {
     366             :   Isolate* isolate(CcTest::InitIsolateOnce());
     367             :   const int kNumParams = 1;
     368           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
     369           4 :   CodeStubAssembler m(asm_tester.state());
     370          16 :   m.Return(m.ToString(m.Parameter(kNumParams + 2), m.Parameter(0)));
     371             : 
     372           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
     373             : 
     374           4 :   Handle<FixedArray> test_cases = isolate->factory()->NewFixedArray(5);
     375           4 :   Handle<FixedArray> smi_test = isolate->factory()->NewFixedArray(2);
     376             :   smi_test->set(0, Smi::FromInt(42));
     377           4 :   Handle<String> str(isolate->factory()->InternalizeUtf8String("42"));
     378           8 :   smi_test->set(1, *str);
     379           8 :   test_cases->set(0, *smi_test);
     380             : 
     381           4 :   Handle<FixedArray> number_test = isolate->factory()->NewFixedArray(2);
     382           4 :   Handle<HeapNumber> num(isolate->factory()->NewHeapNumber(3.14));
     383           8 :   number_test->set(0, *num);
     384           4 :   str = isolate->factory()->InternalizeUtf8String("3.14");
     385           8 :   number_test->set(1, *str);
     386           8 :   test_cases->set(1, *number_test);
     387             : 
     388           4 :   Handle<FixedArray> string_test = isolate->factory()->NewFixedArray(2);
     389           4 :   str = isolate->factory()->InternalizeUtf8String("test");
     390           8 :   string_test->set(0, *str);
     391           8 :   string_test->set(1, *str);
     392           8 :   test_cases->set(2, *string_test);
     393             : 
     394           4 :   Handle<FixedArray> oddball_test = isolate->factory()->NewFixedArray(2);
     395           8 :   oddball_test->set(0, ReadOnlyRoots(isolate).undefined_value());
     396           4 :   str = isolate->factory()->InternalizeUtf8String("undefined");
     397           8 :   oddball_test->set(1, *str);
     398           8 :   test_cases->set(3, *oddball_test);
     399             : 
     400           4 :   Handle<FixedArray> tostring_test = isolate->factory()->NewFixedArray(2);
     401           4 :   Handle<FixedArray> js_array_storage = isolate->factory()->NewFixedArray(2);
     402             :   js_array_storage->set(0, Smi::FromInt(1));
     403             :   js_array_storage->set(1, Smi::FromInt(2));
     404             :   Handle<JSArray> js_array = isolate->factory()->NewJSArray(2);
     405           4 :   JSArray::SetContent(js_array, js_array_storage);
     406           8 :   tostring_test->set(0, *js_array);
     407           4 :   str = isolate->factory()->InternalizeUtf8String("1,2");
     408           8 :   tostring_test->set(1, *str);
     409           8 :   test_cases->set(4, *tostring_test);
     410             : 
     411          44 :   for (int i = 0; i < 5; ++i) {
     412             :     Handle<FixedArray> test =
     413             :         handle(FixedArray::cast(test_cases->get(i)), isolate);
     414          20 :     Handle<Object> obj = handle(test->get(0), isolate);
     415          20 :     Handle<String> expected = handle(String::cast(test->get(1)), isolate);
     416          40 :     Handle<Object> result = ft.Call(obj).ToHandleChecked();
     417          20 :     CHECK(result->IsString());
     418          20 :     CHECK(String::Equals(isolate, Handle<String>::cast(result), expected));
     419             :   }
     420           4 : }
     421             : 
     422       26643 : TEST(TryToName) {
     423             :   Isolate* isolate(CcTest::InitIsolateOnce());
     424             : 
     425             :   const int kNumParams = 3;
     426           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
     427           4 :   CodeStubAssembler m(asm_tester.state());
     428             : 
     429             :   enum Result { kKeyIsIndex, kKeyIsUnique, kBailout };
     430             :   {
     431           4 :     Node* key = m.Parameter(0);
     432           4 :     Node* expected_result = m.Parameter(1);
     433           4 :     Node* expected_arg = m.Parameter(2);
     434             : 
     435           4 :     Label passed(&m), failed(&m);
     436           4 :     Label if_keyisindex(&m), if_keyisunique(&m), if_bailout(&m);
     437             :     {
     438           8 :       Variable var_index(&m, MachineType::PointerRepresentation());
     439           8 :       Variable var_unique(&m, MachineRepresentation::kTagged);
     440             : 
     441             :       m.TryToName(key, &if_keyisindex, &var_index, &if_keyisunique, &var_unique,
     442           4 :                   &if_bailout);
     443             : 
     444           4 :       m.BIND(&if_keyisindex);
     445           4 :       m.GotoIfNot(m.WordEqual(expected_result,
     446           8 :                               m.SmiConstant(Smi::FromInt(kKeyIsIndex))),
     447           4 :                   &failed);
     448          16 :       m.Branch(m.WordEqual(m.SmiUntag(expected_arg), var_index.value()),
     449           4 :                &passed, &failed);
     450             : 
     451           4 :       m.BIND(&if_keyisunique);
     452           4 :       m.GotoIfNot(m.WordEqual(expected_result,
     453           8 :                               m.SmiConstant(Smi::FromInt(kKeyIsUnique))),
     454           4 :                   &failed);
     455          12 :       m.Branch(m.WordEqual(expected_arg, var_unique.value()), &passed, &failed);
     456             :     }
     457             : 
     458           4 :     m.BIND(&if_bailout);
     459           4 :     m.Branch(
     460           8 :         m.WordEqual(expected_result, m.SmiConstant(Smi::FromInt(kBailout))),
     461           4 :         &passed, &failed);
     462             : 
     463           4 :     m.BIND(&passed);
     464           8 :     m.Return(m.BooleanConstant(true));
     465             : 
     466           4 :     m.BIND(&failed);
     467           8 :     m.Return(m.BooleanConstant(false));
     468             :   }
     469             : 
     470           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
     471             : 
     472             :   Handle<Object> expect_index(Smi::FromInt(kKeyIsIndex), isolate);
     473             :   Handle<Object> expect_unique(Smi::FromInt(kKeyIsUnique), isolate);
     474             :   Handle<Object> expect_bailout(Smi::FromInt(kBailout), isolate);
     475             : 
     476             :   {
     477             :     // TryToName(<zero smi>) => if_keyisindex: smi value.
     478             :     Handle<Object> key(Smi::kZero, isolate);
     479           4 :     ft.CheckTrue(key, expect_index, key);
     480             :   }
     481             : 
     482             :   {
     483             :     // TryToName(<positive smi>) => if_keyisindex: smi value.
     484             :     Handle<Object> key(Smi::FromInt(153), isolate);
     485           4 :     ft.CheckTrue(key, expect_index, key);
     486             :   }
     487             : 
     488             :   {
     489             :     // TryToName(<negative smi>) => if_keyisindex: smi value.
     490             :     // A subsequent bounds check needs to take care of this case.
     491             :     Handle<Object> key(Smi::FromInt(-1), isolate);
     492           4 :     ft.CheckTrue(key, expect_index, key);
     493             :   }
     494             : 
     495             :   {
     496             :     // TryToName(<heap number with int value>) => if_keyisindex: number.
     497           4 :     Handle<Object> key(isolate->factory()->NewHeapNumber(153));
     498             :     Handle<Object> index(Smi::FromInt(153), isolate);
     499           4 :     ft.CheckTrue(key, expect_index, index);
     500             :   }
     501             : 
     502             :   {
     503             :     // TryToName(<true>) => if_keyisunique: "true".
     504             :     Handle<Object> key = isolate->factory()->true_value();
     505           4 :     Handle<Object> unique = isolate->factory()->InternalizeUtf8String("true");
     506           4 :     ft.CheckTrue(key, expect_unique, unique);
     507             :   }
     508             : 
     509             :   {
     510             :     // TryToName(<false>) => if_keyisunique: "false".
     511             :     Handle<Object> key = isolate->factory()->false_value();
     512           4 :     Handle<Object> unique = isolate->factory()->InternalizeUtf8String("false");
     513           4 :     ft.CheckTrue(key, expect_unique, unique);
     514             :   }
     515             : 
     516             :   {
     517             :     // TryToName(<null>) => if_keyisunique: "null".
     518             :     Handle<Object> key = isolate->factory()->null_value();
     519           4 :     Handle<Object> unique = isolate->factory()->InternalizeUtf8String("null");
     520           4 :     ft.CheckTrue(key, expect_unique, unique);
     521             :   }
     522             : 
     523             :   {
     524             :     // TryToName(<undefined>) => if_keyisunique: "undefined".
     525             :     Handle<Object> key = isolate->factory()->undefined_value();
     526             :     Handle<Object> unique =
     527           4 :         isolate->factory()->InternalizeUtf8String("undefined");
     528           4 :     ft.CheckTrue(key, expect_unique, unique);
     529             :   }
     530             : 
     531             :   {
     532             :     // TryToName(<symbol>) => if_keyisunique: <symbol>.
     533           4 :     Handle<Object> key = isolate->factory()->NewSymbol();
     534           4 :     ft.CheckTrue(key, expect_unique, key);
     535             :   }
     536             : 
     537             :   {
     538             :     // TryToName(<internalized string>) => if_keyisunique: <internalized string>
     539           4 :     Handle<Object> key = isolate->factory()->InternalizeUtf8String("test");
     540           4 :     ft.CheckTrue(key, expect_unique, key);
     541             :   }
     542             : 
     543             :   {
     544             :     // TryToName(<internalized number string>) => if_keyisindex: number.
     545           4 :     Handle<Object> key = isolate->factory()->InternalizeUtf8String("153");
     546             :     Handle<Object> index(Smi::FromInt(153), isolate);
     547           4 :     ft.CheckTrue(key, expect_index, index);
     548             :   }
     549             : 
     550             :   {
     551             :     // TryToName(<internalized uncacheable number string>) => bailout
     552             :     Handle<Object> key =
     553           4 :         isolate->factory()->InternalizeUtf8String("4294967294");
     554             :     ft.CheckTrue(key, expect_bailout);
     555             :   }
     556             : 
     557             :   {
     558             :     // TryToName(<non-internalized number string>) => if_keyisindex: number.
     559           4 :     Handle<String> key = isolate->factory()->NewStringFromAsciiChecked("153");
     560             :     uint32_t dummy;
     561           4 :     CHECK(key->AsArrayIndex(&dummy));
     562           4 :     CHECK(key->HasHashCode());
     563           4 :     CHECK(!key->IsInternalizedString());
     564             :     Handle<Object> index(Smi::FromInt(153), isolate);
     565           4 :     ft.CheckTrue(key, expect_index, index);
     566             :   }
     567             : 
     568             :   {
     569             :     // TryToName(<number string without cached index>) => bailout.
     570           4 :     Handle<String> key = isolate->factory()->NewStringFromAsciiChecked("153");
     571           4 :     CHECK(!key->HasHashCode());
     572             :     ft.CheckTrue(key, expect_bailout);
     573             :   }
     574             : 
     575             :   {
     576             :     // TryToName(<non-internalized string>) => bailout.
     577           4 :     Handle<Object> key = isolate->factory()->NewStringFromAsciiChecked("test");
     578             :     ft.CheckTrue(key, expect_bailout);
     579             :   }
     580             : 
     581           4 :   if (FLAG_thin_strings) {
     582             :     // TryToName(<thin string>) => internalized version.
     583           4 :     Handle<String> s = isolate->factory()->NewStringFromAsciiChecked("foo");
     584           4 :     Handle<String> internalized = isolate->factory()->InternalizeString(s);
     585           4 :     ft.CheckTrue(s, expect_unique, internalized);
     586             :   }
     587             : 
     588           4 :   if (FLAG_thin_strings) {
     589             :     // TryToName(<thin two-byte string>) => internalized version.
     590           4 :     uc16 array1[] = {2001, 2002, 2003};
     591             :     Vector<const uc16> str1(array1);
     592             :     Handle<String> s =
     593           8 :         isolate->factory()->NewStringFromTwoByte(str1).ToHandleChecked();
     594           4 :     Handle<String> internalized = isolate->factory()->InternalizeString(s);
     595           4 :     ft.CheckTrue(s, expect_unique, internalized);
     596             :   }
     597           4 : }
     598             : 
     599             : namespace {
     600             : 
     601             : template <typename Dictionary>
     602           8 : void TestEntryToIndex() {
     603             :   Isolate* isolate(CcTest::InitIsolateOnce());
     604             : 
     605             :   const int kNumParams = 1;
     606          16 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
     607           8 :   CodeStubAssembler m(asm_tester.state());
     608             :   {
     609          16 :     TNode<IntPtrT> entry = m.SmiUntag(m.Parameter(0));
     610             :     TNode<IntPtrT> result = m.EntryToIndex<Dictionary>(entry);
     611          16 :     m.Return(m.SmiTag(result));
     612             :   }
     613             : 
     614           8 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
     615             : 
     616             :   // Test a wide range of entries but staying linear in the first 100 entries.
     617       22736 :   for (int entry = 0; entry < Dictionary::kMaxCapacity;
     618             :        entry = entry * 1.01 + 1) {
     619             :     Handle<Object> result =
     620       22728 :         ft.Call(handle(Smi::FromInt(entry), isolate)).ToHandleChecked();
     621       11364 :     CHECK_EQ(Dictionary::EntryToIndex(entry), Smi::ToInt(*result));
     622             :   }
     623           8 : }
     624             : 
     625       26643 : TEST(NameDictionaryEntryToIndex) { TestEntryToIndex<NameDictionary>(); }
     626       26643 : TEST(GlobalDictionaryEntryToIndex) { TestEntryToIndex<GlobalDictionary>(); }
     627             : 
     628             : }  // namespace
     629             : 
     630             : namespace {
     631             : 
     632             : template <typename Dictionary>
     633           8 : void TestNameDictionaryLookup() {
     634             :   Isolate* isolate(CcTest::InitIsolateOnce());
     635             : 
     636             :   const int kNumParams = 4;
     637          16 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
     638           8 :   CodeStubAssembler m(asm_tester.state());
     639             : 
     640             :   enum Result { kFound, kNotFound };
     641             :   {
     642           8 :     TNode<Dictionary> dictionary = m.CAST(m.Parameter(0));
     643           8 :     TNode<Name> unique_name = m.CAST(m.Parameter(1));
     644           8 :     TNode<Smi> expected_result = m.CAST(m.Parameter(2));
     645           8 :     TNode<Object> expected_arg = m.CAST(m.Parameter(3));
     646             : 
     647           8 :     Label passed(&m), failed(&m);
     648           8 :     Label if_found(&m), if_not_found(&m);
     649             :     TVariable<IntPtrT> var_name_index(&m);
     650             : 
     651           8 :     m.NameDictionaryLookup<Dictionary>(dictionary, unique_name, &if_found,
     652             :                                        &var_name_index, &if_not_found);
     653           8 :     m.BIND(&if_found);
     654          16 :     m.GotoIfNot(
     655             :         m.WordEqual(expected_result, m.SmiConstant(Smi::FromInt(kFound))),
     656             :         &failed);
     657          16 :     m.Branch(
     658          16 :         m.WordEqual(m.SmiUntag(m.CAST(expected_arg)), var_name_index.value()),
     659             :         &passed, &failed);
     660             : 
     661           8 :     m.BIND(&if_not_found);
     662          16 :     m.Branch(
     663             :         m.WordEqual(expected_result, m.SmiConstant(Smi::FromInt(kNotFound))),
     664             :         &passed, &failed);
     665             : 
     666           8 :     m.BIND(&passed);
     667          16 :     m.Return(m.BooleanConstant(true));
     668             : 
     669           8 :     m.BIND(&failed);
     670          16 :     m.Return(m.BooleanConstant(false));
     671             :   }
     672             : 
     673           8 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
     674             : 
     675             :   Handle<Object> expect_found(Smi::FromInt(kFound), isolate);
     676             :   Handle<Object> expect_not_found(Smi::FromInt(kNotFound), isolate);
     677             : 
     678           8 :   Handle<Dictionary> dictionary = Dictionary::New(isolate, 40);
     679           8 :   PropertyDetails fake_details = PropertyDetails::Empty();
     680             : 
     681             :   Factory* factory = isolate->factory();
     682             :   Handle<Name> keys[] = {
     683             :       factory->InternalizeUtf8String("0"),
     684             :       factory->InternalizeUtf8String("42"),
     685             :       factory->InternalizeUtf8String("-153"),
     686             :       factory->InternalizeUtf8String("0.0"),
     687             :       factory->InternalizeUtf8String("4.2"),
     688             :       factory->InternalizeUtf8String(""),
     689             :       factory->InternalizeUtf8String("name"),
     690             :       factory->NewSymbol(),
     691             :       factory->NewPrivateSymbol(),
     692          72 :   };
     693             : 
     694         152 :   for (size_t i = 0; i < arraysize(keys); i++) {
     695          72 :     Handle<Object> value = factory->NewPropertyCell(keys[i]);
     696          72 :     dictionary =
     697             :         Dictionary::Add(isolate, dictionary, keys[i], value, fake_details);
     698             :   }
     699             : 
     700         152 :   for (size_t i = 0; i < arraysize(keys); i++) {
     701          72 :     int entry = dictionary->FindEntry(isolate, keys[i]);
     702             :     int name_index =
     703             :         Dictionary::EntryToIndex(entry) + Dictionary::kEntryKeyIndex;
     704          72 :     CHECK_NE(Dictionary::kNotFound, entry);
     705             : 
     706             :     Handle<Object> expected_name_index(Smi::FromInt(name_index), isolate);
     707             :     ft.CheckTrue(dictionary, keys[i], expect_found, expected_name_index);
     708             :   }
     709             : 
     710             :   Handle<Name> non_existing_keys[] = {
     711             :       factory->InternalizeUtf8String("1"),
     712             :       factory->InternalizeUtf8String("-42"),
     713             :       factory->InternalizeUtf8String("153"),
     714             :       factory->InternalizeUtf8String("-1.0"),
     715             :       factory->InternalizeUtf8String("1.3"),
     716             :       factory->InternalizeUtf8String("a"),
     717             :       factory->InternalizeUtf8String("boom"),
     718             :       factory->NewSymbol(),
     719             :       factory->NewPrivateSymbol(),
     720          72 :   };
     721             : 
     722         152 :   for (size_t i = 0; i < arraysize(non_existing_keys); i++) {
     723          72 :     int entry = dictionary->FindEntry(isolate, non_existing_keys[i]);
     724          72 :     CHECK_EQ(Dictionary::kNotFound, entry);
     725             : 
     726          72 :     ft.CheckTrue(dictionary, non_existing_keys[i], expect_not_found);
     727             :   }
     728           8 : }
     729             : 
     730             : }  // namespace
     731             : 
     732       26643 : TEST(NameDictionaryLookup) { TestNameDictionaryLookup<NameDictionary>(); }
     733             : 
     734       26643 : TEST(GlobalDictionaryLookup) { TestNameDictionaryLookup<GlobalDictionary>(); }
     735             : 
     736       26643 : TEST(NumberDictionaryLookup) {
     737             :   Isolate* isolate(CcTest::InitIsolateOnce());
     738             : 
     739             :   const int kNumParams = 4;
     740           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
     741           4 :   CodeStubAssembler m(asm_tester.state());
     742             : 
     743             :   enum Result { kFound, kNotFound };
     744             :   {
     745           4 :     TNode<NumberDictionary> dictionary = m.CAST(m.Parameter(0));
     746           8 :     TNode<IntPtrT> key = m.SmiUntag(m.Parameter(1));
     747           4 :     TNode<Smi> expected_result = m.CAST(m.Parameter(2));
     748           4 :     TNode<Object> expected_arg = m.CAST(m.Parameter(3));
     749             : 
     750           4 :     Label passed(&m), failed(&m);
     751           4 :     Label if_found(&m), if_not_found(&m);
     752             :     TVariable<IntPtrT> var_entry(&m);
     753             : 
     754             :     m.NumberDictionaryLookup(dictionary, key, &if_found, &var_entry,
     755           4 :                              &if_not_found);
     756           4 :     m.BIND(&if_found);
     757           4 :     m.GotoIfNot(
     758           4 :         m.WordEqual(expected_result, m.SmiConstant(Smi::FromInt(kFound))),
     759           4 :         &failed);
     760          12 :     m.Branch(m.WordEqual(m.SmiUntag(m.CAST(expected_arg)), var_entry.value()),
     761           4 :              &passed, &failed);
     762             : 
     763           4 :     m.BIND(&if_not_found);
     764           4 :     m.Branch(
     765           4 :         m.WordEqual(expected_result, m.SmiConstant(Smi::FromInt(kNotFound))),
     766           4 :         &passed, &failed);
     767             : 
     768           4 :     m.BIND(&passed);
     769           8 :     m.Return(m.BooleanConstant(true));
     770             : 
     771           4 :     m.BIND(&failed);
     772           8 :     m.Return(m.BooleanConstant(false));
     773             :   }
     774             : 
     775           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
     776             : 
     777             :   Handle<Object> expect_found(Smi::FromInt(kFound), isolate);
     778             :   Handle<Object> expect_not_found(Smi::FromInt(kNotFound), isolate);
     779             : 
     780             :   const int kKeysCount = 1000;
     781             :   Handle<NumberDictionary> dictionary =
     782           4 :       NumberDictionary::New(isolate, kKeysCount);
     783             :   uint32_t keys[kKeysCount];
     784             : 
     785             :   Handle<Object> fake_value(Smi::FromInt(42), isolate);
     786           4 :   PropertyDetails fake_details = PropertyDetails::Empty();
     787             : 
     788           4 :   base::RandomNumberGenerator rand_gen(FLAG_random_seed);
     789             : 
     790        8004 :   for (int i = 0; i < kKeysCount; i++) {
     791        4000 :     int random_key = rand_gen.NextInt(Smi::kMaxValue);
     792        4000 :     keys[i] = static_cast<uint32_t>(random_key);
     793        4000 :     if (dictionary->FindEntry(isolate, keys[i]) != NumberDictionary::kNotFound)
     794             :       continue;
     795             : 
     796             :     dictionary = NumberDictionary::Add(isolate, dictionary, keys[i], fake_value,
     797        4000 :                                        fake_details);
     798             :   }
     799             : 
     800             :   // Now try querying existing keys.
     801        8004 :   for (int i = 0; i < kKeysCount; i++) {
     802        8000 :     int entry = dictionary->FindEntry(isolate, keys[i]);
     803        4000 :     CHECK_NE(NumberDictionary::kNotFound, entry);
     804             : 
     805        4000 :     Handle<Object> key(Smi::FromInt(keys[i]), isolate);
     806             :     Handle<Object> expected_entry(Smi::FromInt(entry), isolate);
     807             :     ft.CheckTrue(dictionary, key, expect_found, expected_entry);
     808             :   }
     809             : 
     810             :   // Now try querying random keys which do not exist in the dictionary.
     811        4004 :   for (int i = 0; i < kKeysCount;) {
     812        4000 :     int random_key = rand_gen.NextInt(Smi::kMaxValue);
     813        8000 :     int entry = dictionary->FindEntry(isolate, random_key);
     814        4000 :     if (entry != NumberDictionary::kNotFound) continue;
     815        4000 :     i++;
     816             : 
     817             :     Handle<Object> key(Smi::FromInt(random_key), isolate);
     818        4000 :     ft.CheckTrue(dictionary, key, expect_not_found);
     819             :   }
     820           4 : }
     821             : 
     822       26643 : TEST(TransitionLookup) {
     823             :   Isolate* isolate(CcTest::InitIsolateOnce());
     824             : 
     825             :   const int kNumParams = 4;
     826           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
     827             : 
     828             :   enum Result { kFound, kNotFound };
     829             : 
     830           4 :   class TempAssembler : public CodeStubAssembler {
     831             :    public:
     832             :     explicit TempAssembler(compiler::CodeAssemblerState* state)
     833           4 :         : CodeStubAssembler(state) {}
     834             : 
     835           4 :     void Generate() {
     836           4 :       TNode<TransitionArray> transitions = CAST(Parameter(0));
     837           4 :       TNode<Name> name = CAST(Parameter(1));
     838           4 :       TNode<Smi> expected_result = CAST(Parameter(2));
     839           4 :       TNode<Object> expected_arg = CAST(Parameter(3));
     840             : 
     841           4 :       Label passed(this), failed(this);
     842           4 :       Label if_found(this), if_not_found(this);
     843             :       TVARIABLE(IntPtrT, var_transition_index);
     844             : 
     845           8 :       TransitionLookup(name, transitions, &if_found, &var_transition_index,
     846           4 :                        &if_not_found);
     847             : 
     848           4 :       BIND(&if_found);
     849           4 :       GotoIfNot(WordEqual(expected_result, SmiConstant(kFound)), &failed);
     850           8 :       Branch(WordEqual(expected_arg, SmiTag(var_transition_index.value())),
     851           4 :              &passed, &failed);
     852             : 
     853           4 :       BIND(&if_not_found);
     854           4 :       Branch(WordEqual(expected_result, SmiConstant(kNotFound)), &passed,
     855           4 :              &failed);
     856             : 
     857           4 :       BIND(&passed);
     858           8 :       Return(BooleanConstant(true));
     859             : 
     860           4 :       BIND(&failed);
     861           8 :       Return(BooleanConstant(false));
     862           4 :     }
     863             :   };
     864           8 :   TempAssembler(asm_tester.state()).Generate();
     865             : 
     866           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
     867             : 
     868             :   Handle<Object> expect_found(Smi::FromInt(kFound), isolate);
     869             :   Handle<Object> expect_not_found(Smi::FromInt(kNotFound), isolate);
     870             : 
     871             :   const int ATTRS_COUNT = (READ_ONLY | DONT_ENUM | DONT_DELETE) + 1;
     872             :   STATIC_ASSERT(ATTRS_COUNT == 8);
     873             : 
     874             :   const int kKeysCount = 300;
     875           4 :   Handle<Map> root_map = Map::Create(isolate, 0);
     876        2404 :   Handle<Name> keys[kKeysCount];
     877             : 
     878           4 :   base::RandomNumberGenerator rand_gen(FLAG_random_seed);
     879             : 
     880             :   Factory* factory = isolate->factory();
     881           4 :   Handle<FieldType> any = FieldType::Any(isolate);
     882             : 
     883        2404 :   for (int i = 0; i < kKeysCount; i++) {
     884             :     Handle<Name> name;
     885        1200 :     if (i % 30 == 0) {
     886          40 :       name = factory->NewPrivateSymbol();
     887        1160 :     } else if (i % 10 == 0) {
     888          80 :       name = factory->NewSymbol();
     889             :     } else {
     890        1080 :       int random_key = rand_gen.NextInt(Smi::kMaxValue);
     891        1080 :       name = MakeName("p", random_key);
     892             :     }
     893        1200 :     keys[i] = name;
     894             : 
     895        1200 :     bool is_private = name->IsPrivate();
     896        1200 :     PropertyAttributes base_attributes = is_private ? DONT_ENUM : NONE;
     897             : 
     898             :     // Ensure that all the combinations of cases are covered:
     899             :     // 1) there is a "base" attributes transition
     900             :     // 2) there are other non-base attributes transitions
     901        1200 :     if ((i & 1) == 0) {
     902        1200 :       CHECK(!Map::CopyWithField(isolate, root_map, name, any, base_attributes,
     903             :                                 PropertyConstness::kMutable,
     904             :                                 Representation::Tagged(), INSERT_TRANSITION)
     905             :                  .is_null());
     906             :     }
     907             : 
     908        1200 :     if ((i & 2) == 0) {
     909       10200 :       for (int j = 0; j < ATTRS_COUNT; j++) {
     910        4800 :         PropertyAttributes attributes = static_cast<PropertyAttributes>(j);
     911        4800 :         if (attributes == base_attributes) continue;
     912             :         // Don't add private symbols with enumerable attributes.
     913        4200 :         if (is_private && ((attributes & DONT_ENUM) == 0)) continue;
     914        8240 :         CHECK(!Map::CopyWithField(isolate, root_map, name, any, attributes,
     915             :                                   PropertyConstness::kMutable,
     916             :                                   Representation::Tagged(), INSERT_TRANSITION)
     917             :                    .is_null());
     918             :       }
     919             :     }
     920             :   }
     921             : 
     922           4 :   CHECK(root_map->raw_transitions()
     923             :             ->GetHeapObjectAssumeStrong()
     924             :             ->IsTransitionArray());
     925             :   Handle<TransitionArray> transitions(
     926             :       TransitionArray::cast(
     927             :           root_map->raw_transitions()->GetHeapObjectAssumeStrong()),
     928             :       isolate);
     929             :   DCHECK(transitions->IsSortedNoDuplicates());
     930             : 
     931             :   // Ensure we didn't overflow transition array and therefore all the
     932             :   // combinations of cases are covered.
     933           4 :   CHECK(TransitionsAccessor(isolate, root_map).CanHaveMoreTransitions());
     934             : 
     935             :   // Now try querying keys.
     936             :   bool positive_lookup_tested = false;
     937             :   bool negative_lookup_tested = false;
     938        2404 :   for (int i = 0; i < kKeysCount; i++) {
     939        1200 :     Handle<Name> name = keys[i];
     940             : 
     941        1200 :     int transition_number = transitions->SearchNameForTesting(*name);
     942             : 
     943        1200 :     if (transition_number != TransitionArray::kNotFound) {
     944             :       Handle<Smi> expected_value(
     945             :           Smi::FromInt(TransitionArray::ToKeyIndex(transition_number)),
     946             :           isolate);
     947             :       ft.CheckTrue(transitions, name, expect_found, expected_value);
     948             :       positive_lookup_tested = true;
     949             :     } else {
     950         300 :       ft.CheckTrue(transitions, name, expect_not_found);
     951             :       negative_lookup_tested = true;
     952             :     }
     953             :   }
     954           4 :   CHECK(positive_lookup_tested);
     955           4 :   CHECK(negative_lookup_tested);
     956           4 : }
     957             : 
     958             : namespace {
     959             : 
     960          20 : void AddProperties(Handle<JSObject> object, Handle<Name> names[],
     961             :                    size_t count) {
     962             :   Isolate* isolate = object->GetIsolate();
     963         380 :   for (size_t i = 0; i < count; i++) {
     964         180 :     Handle<Object> value(Smi::FromInt(static_cast<int>(42 + i)), isolate);
     965         180 :     JSObject::AddProperty(isolate, object, names[i], value, NONE);
     966             :   }
     967          20 : }
     968             : 
     969          12 : Handle<AccessorPair> CreateAccessorPair(FunctionTester* ft,
     970             :                                         const char* getter_body,
     971             :                                         const char* setter_body) {
     972          12 :   Handle<AccessorPair> pair = ft->isolate->factory()->NewAccessorPair();
     973          12 :   if (getter_body) {
     974          24 :     pair->set_getter(*ft->NewFunction(getter_body));
     975             :   }
     976          12 :   if (setter_body) {
     977          24 :     pair->set_setter(*ft->NewFunction(setter_body));
     978             :   }
     979          12 :   return pair;
     980             : }
     981             : 
     982          20 : void AddProperties(Handle<JSObject> object, Handle<Name> names[],
     983             :                    size_t names_count, Handle<Object> values[],
     984             :                    size_t values_count, int seed = 0) {
     985             :   Isolate* isolate = object->GetIsolate();
     986         700 :   for (size_t i = 0; i < names_count; i++) {
     987         340 :     Handle<Object> value = values[(seed + i) % values_count];
     988         340 :     if (value->IsAccessorPair()) {
     989             :       Handle<AccessorPair> pair = Handle<AccessorPair>::cast(value);
     990             :       Handle<Object> getter(pair->getter(), isolate);
     991             :       Handle<Object> setter(pair->setter(), isolate);
     992         160 :       JSObject::DefineAccessor(object, names[i], getter, setter, NONE).Check();
     993             :     } else {
     994         260 :       JSObject::AddProperty(isolate, object, names[i], value, NONE);
     995             :     }
     996             :   }
     997          20 : }
     998             : 
     999             : }  // namespace
    1000             : 
    1001       26643 : TEST(TryHasOwnProperty) {
    1002             :   Isolate* isolate(CcTest::InitIsolateOnce());
    1003             : 
    1004             :   const int kNumParams = 4;
    1005           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    1006           4 :   CodeStubAssembler m(asm_tester.state());
    1007             : 
    1008             :   enum Result { kFound, kNotFound, kBailout };
    1009             :   {
    1010           4 :     Node* object = m.Parameter(0);
    1011           4 :     Node* unique_name = m.Parameter(1);
    1012           4 :     Node* expected_result = m.Parameter(2);
    1013             : 
    1014           4 :     Label passed(&m), failed(&m);
    1015           4 :     Label if_found(&m), if_not_found(&m), if_bailout(&m);
    1016             : 
    1017           8 :     Node* map = m.LoadMap(object);
    1018           8 :     Node* instance_type = m.LoadMapInstanceType(map);
    1019             : 
    1020             :     m.TryHasOwnProperty(object, map, instance_type, unique_name, &if_found,
    1021           4 :                         &if_not_found, &if_bailout);
    1022             : 
    1023           4 :     m.BIND(&if_found);
    1024           8 :     m.Branch(m.WordEqual(expected_result, m.SmiConstant(Smi::FromInt(kFound))),
    1025           4 :              &passed, &failed);
    1026             : 
    1027           4 :     m.BIND(&if_not_found);
    1028           4 :     m.Branch(
    1029           8 :         m.WordEqual(expected_result, m.SmiConstant(Smi::FromInt(kNotFound))),
    1030           4 :         &passed, &failed);
    1031             : 
    1032           4 :     m.BIND(&if_bailout);
    1033           4 :     m.Branch(
    1034           8 :         m.WordEqual(expected_result, m.SmiConstant(Smi::FromInt(kBailout))),
    1035           4 :         &passed, &failed);
    1036             : 
    1037           4 :     m.BIND(&passed);
    1038           8 :     m.Return(m.BooleanConstant(true));
    1039             : 
    1040           4 :     m.BIND(&failed);
    1041           8 :     m.Return(m.BooleanConstant(false));
    1042             :   }
    1043             : 
    1044           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    1045             : 
    1046             :   Handle<Object> expect_found(Smi::FromInt(kFound), isolate);
    1047             :   Handle<Object> expect_not_found(Smi::FromInt(kNotFound), isolate);
    1048             :   Handle<Object> expect_bailout(Smi::FromInt(kBailout), isolate);
    1049             : 
    1050             :   Factory* factory = isolate->factory();
    1051             : 
    1052             :   Handle<Name> deleted_property_name =
    1053           4 :       factory->InternalizeUtf8String("deleted");
    1054             : 
    1055             :   Handle<Name> names[] = {
    1056             :       factory->InternalizeUtf8String("a"),
    1057             :       factory->InternalizeUtf8String("bb"),
    1058             :       factory->InternalizeUtf8String("ccc"),
    1059             :       factory->InternalizeUtf8String("dddd"),
    1060             :       factory->InternalizeUtf8String("eeeee"),
    1061             :       factory->InternalizeUtf8String(""),
    1062             :       factory->InternalizeUtf8String("name"),
    1063             :       factory->NewSymbol(),
    1064             :       factory->NewPrivateSymbol(),
    1065          36 :   };
    1066             : 
    1067             :   std::vector<Handle<JSObject>> objects;
    1068             : 
    1069             :   {
    1070             :     // Fast object, no inobject properties.
    1071             :     int inobject_properties = 0;
    1072           4 :     Handle<Map> map = Map::Create(isolate, inobject_properties);
    1073           4 :     Handle<JSObject> object = factory->NewJSObjectFromMap(map);
    1074           4 :     AddProperties(object, names, arraysize(names));
    1075           4 :     CHECK_EQ(JS_OBJECT_TYPE, object->map()->instance_type());
    1076           4 :     CHECK_EQ(inobject_properties, object->map()->GetInObjectProperties());
    1077           4 :     CHECK(!object->map()->is_dictionary_map());
    1078           4 :     objects.push_back(object);
    1079             :   }
    1080             : 
    1081             :   {
    1082             :     // Fast object, all inobject properties.
    1083             :     int inobject_properties = arraysize(names) * 2;
    1084           4 :     Handle<Map> map = Map::Create(isolate, inobject_properties);
    1085           4 :     Handle<JSObject> object = factory->NewJSObjectFromMap(map);
    1086           4 :     AddProperties(object, names, arraysize(names));
    1087           4 :     CHECK_EQ(JS_OBJECT_TYPE, object->map()->instance_type());
    1088           4 :     CHECK_EQ(inobject_properties, object->map()->GetInObjectProperties());
    1089           4 :     CHECK(!object->map()->is_dictionary_map());
    1090           4 :     objects.push_back(object);
    1091             :   }
    1092             : 
    1093             :   {
    1094             :     // Fast object, half inobject properties.
    1095             :     int inobject_properties = arraysize(names) / 2;
    1096           4 :     Handle<Map> map = Map::Create(isolate, inobject_properties);
    1097           4 :     Handle<JSObject> object = factory->NewJSObjectFromMap(map);
    1098           4 :     AddProperties(object, names, arraysize(names));
    1099           4 :     CHECK_EQ(JS_OBJECT_TYPE, object->map()->instance_type());
    1100           4 :     CHECK_EQ(inobject_properties, object->map()->GetInObjectProperties());
    1101           4 :     CHECK(!object->map()->is_dictionary_map());
    1102           4 :     objects.push_back(object);
    1103             :   }
    1104             : 
    1105             :   {
    1106             :     // Dictionary mode object.
    1107             :     Handle<JSFunction> function =
    1108           4 :         factory->NewFunctionForTest(factory->empty_string());
    1109           4 :     Handle<JSObject> object = factory->NewJSObject(function);
    1110           4 :     AddProperties(object, names, arraysize(names));
    1111           4 :     JSObject::NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0, "test");
    1112             : 
    1113           4 :     JSObject::AddProperty(isolate, object, deleted_property_name, object, NONE);
    1114           8 :     CHECK(JSObject::DeleteProperty(object, deleted_property_name,
    1115             :                                    LanguageMode::kSloppy)
    1116             :               .FromJust());
    1117             : 
    1118           4 :     CHECK_EQ(JS_OBJECT_TYPE, object->map()->instance_type());
    1119           4 :     CHECK(object->map()->is_dictionary_map());
    1120           4 :     objects.push_back(object);
    1121             :   }
    1122             : 
    1123             :   {
    1124             :     // Global object.
    1125             :     Handle<JSFunction> function =
    1126           4 :         factory->NewFunctionForTest(factory->empty_string());
    1127           4 :     JSFunction::EnsureHasInitialMap(function);
    1128             :     function->initial_map()->set_instance_type(JS_GLOBAL_OBJECT_TYPE);
    1129             :     function->initial_map()->set_is_prototype_map(true);
    1130           4 :     function->initial_map()->set_is_dictionary_map(true);
    1131           4 :     function->initial_map()->set_may_have_interesting_symbols(true);
    1132           4 :     Handle<JSObject> object = factory->NewJSGlobalObject(function);
    1133           4 :     AddProperties(object, names, arraysize(names));
    1134             : 
    1135           4 :     JSObject::AddProperty(isolate, object, deleted_property_name, object, NONE);
    1136           8 :     CHECK(JSObject::DeleteProperty(object, deleted_property_name,
    1137             :                                    LanguageMode::kSloppy)
    1138             :               .FromJust());
    1139             : 
    1140           4 :     CHECK_EQ(JS_GLOBAL_OBJECT_TYPE, object->map()->instance_type());
    1141           4 :     CHECK(object->map()->is_dictionary_map());
    1142           4 :     objects.push_back(object);
    1143             :   }
    1144             : 
    1145             :   {
    1146          24 :     for (Handle<JSObject> object : objects) {
    1147         380 :       for (size_t name_index = 0; name_index < arraysize(names); name_index++) {
    1148         180 :         Handle<Name> name = names[name_index];
    1149         360 :         CHECK(JSReceiver::HasProperty(object, name).FromJust());
    1150         180 :         ft.CheckTrue(object, name, expect_found);
    1151             :       }
    1152             :     }
    1153             :   }
    1154             : 
    1155             :   {
    1156             :     Handle<Name> non_existing_names[] = {
    1157             :         factory->NewSymbol(),
    1158             :         factory->InternalizeUtf8String("ne_a"),
    1159             :         factory->InternalizeUtf8String("ne_bb"),
    1160             :         factory->NewPrivateSymbol(),
    1161             :         factory->InternalizeUtf8String("ne_ccc"),
    1162             :         factory->InternalizeUtf8String("ne_dddd"),
    1163             :         deleted_property_name,
    1164          28 :     };
    1165          24 :     for (Handle<JSObject> object : objects) {
    1166         300 :       for (size_t key_index = 0; key_index < arraysize(non_existing_names);
    1167             :            key_index++) {
    1168         140 :         Handle<Name> name = non_existing_names[key_index];
    1169         280 :         CHECK(!JSReceiver::HasProperty(object, name).FromJust());
    1170         140 :         ft.CheckTrue(object, name, expect_not_found);
    1171             :       }
    1172             :     }
    1173             :   }
    1174             : 
    1175             :   {
    1176             :     Handle<JSFunction> function =
    1177           4 :         factory->NewFunctionForTest(factory->empty_string());
    1178           4 :     Handle<JSProxy> object = factory->NewJSProxy(function, objects[0]);
    1179           4 :     CHECK_EQ(JS_PROXY_TYPE, object->map()->instance_type());
    1180           4 :     ft.CheckTrue(object, names[0], expect_bailout);
    1181             :   }
    1182             : 
    1183             :   {
    1184           4 :     Handle<JSObject> object = isolate->global_proxy();
    1185           4 :     CHECK_EQ(JS_GLOBAL_PROXY_TYPE, object->map()->instance_type());
    1186           4 :     ft.CheckTrue(object, names[0], expect_bailout);
    1187             :   }
    1188           4 : }
    1189             : 
    1190       26643 : TEST(TryGetOwnProperty) {
    1191             :   Isolate* isolate(CcTest::InitIsolateOnce());
    1192             :   Factory* factory = isolate->factory();
    1193             : 
    1194             :   const int kNumParams = 2;
    1195           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    1196           4 :   CodeStubAssembler m(asm_tester.state());
    1197             : 
    1198           4 :   Handle<Symbol> not_found_symbol = factory->NewSymbol();
    1199           4 :   Handle<Symbol> bailout_symbol = factory->NewSymbol();
    1200             :   {
    1201           4 :     Node* object = m.Parameter(0);
    1202           4 :     Node* unique_name = m.Parameter(1);
    1203           4 :     Node* context = m.Parameter(kNumParams + 2);
    1204             : 
    1205           8 :     Variable var_value(&m, MachineRepresentation::kTagged);
    1206           4 :     Label if_found(&m), if_not_found(&m), if_bailout(&m);
    1207             : 
    1208           8 :     Node* map = m.LoadMap(object);
    1209           8 :     Node* instance_type = m.LoadMapInstanceType(map);
    1210             : 
    1211             :     m.TryGetOwnProperty(context, object, object, map, instance_type,
    1212             :                         unique_name, &if_found, &var_value, &if_not_found,
    1213           4 :                         &if_bailout);
    1214             : 
    1215           4 :     m.BIND(&if_found);
    1216           8 :     m.Return(var_value.value());
    1217             : 
    1218           4 :     m.BIND(&if_not_found);
    1219           4 :     m.Return(m.HeapConstant(not_found_symbol));
    1220             : 
    1221           4 :     m.BIND(&if_bailout);
    1222           4 :     m.Return(m.HeapConstant(bailout_symbol));
    1223             :   }
    1224             : 
    1225           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    1226             : 
    1227             :   Handle<Name> deleted_property_name =
    1228           4 :       factory->InternalizeUtf8String("deleted");
    1229             : 
    1230             :   Handle<Name> names[] = {
    1231             :       factory->InternalizeUtf8String("bb"),
    1232             :       factory->NewSymbol(),
    1233             :       factory->InternalizeUtf8String("a"),
    1234             :       factory->InternalizeUtf8String("ccc"),
    1235             :       factory->InternalizeUtf8String("esajefe"),
    1236             :       factory->NewPrivateSymbol(),
    1237             :       factory->InternalizeUtf8String("eeeee"),
    1238             :       factory->InternalizeUtf8String("p1"),
    1239             :       factory->InternalizeUtf8String("acshw23e"),
    1240             :       factory->InternalizeUtf8String(""),
    1241             :       factory->InternalizeUtf8String("dddd"),
    1242             :       factory->NewPrivateSymbol(),
    1243             :       factory->InternalizeUtf8String("name"),
    1244             :       factory->InternalizeUtf8String("p2"),
    1245             :       factory->InternalizeUtf8String("p3"),
    1246             :       factory->InternalizeUtf8String("p4"),
    1247             :       factory->NewPrivateSymbol(),
    1248          68 :   };
    1249             :   Handle<Object> values[] = {
    1250             :       factory->NewFunctionForTest(factory->empty_string()),
    1251             :       factory->NewSymbol(),
    1252             :       factory->InternalizeUtf8String("a"),
    1253             :       CreateAccessorPair(&ft, "() => 188;", "() => 199;"),
    1254             :       factory->NewFunctionForTest(factory->InternalizeUtf8String("bb")),
    1255             :       factory->InternalizeUtf8String("ccc"),
    1256             :       CreateAccessorPair(&ft, "() => 88;", nullptr),
    1257             :       handle(Smi::FromInt(1), isolate),
    1258             :       factory->InternalizeUtf8String(""),
    1259             :       CreateAccessorPair(&ft, nullptr, "() => 99;"),
    1260             :       factory->NewHeapNumber(4.2),
    1261             :       handle(Smi::FromInt(153), isolate),
    1262             :       factory->NewJSObject(
    1263             :           factory->NewFunctionForTest(factory->empty_string())),
    1264             :       factory->NewPrivateSymbol(),
    1265          48 :   };
    1266             :   STATIC_ASSERT(arraysize(values) < arraysize(names));
    1267             : 
    1268           4 :   base::RandomNumberGenerator rand_gen(FLAG_random_seed);
    1269             : 
    1270             :   std::vector<Handle<JSObject>> objects;
    1271             : 
    1272             :   {
    1273             :     // Fast object, no inobject properties.
    1274             :     int inobject_properties = 0;
    1275           4 :     Handle<Map> map = Map::Create(isolate, inobject_properties);
    1276           4 :     Handle<JSObject> object = factory->NewJSObjectFromMap(map);
    1277             :     AddProperties(object, names, arraysize(names), values, arraysize(values),
    1278           4 :                   rand_gen.NextInt());
    1279           4 :     CHECK_EQ(JS_OBJECT_TYPE, object->map()->instance_type());
    1280           4 :     CHECK_EQ(inobject_properties, object->map()->GetInObjectProperties());
    1281           4 :     CHECK(!object->map()->is_dictionary_map());
    1282           4 :     objects.push_back(object);
    1283             :   }
    1284             : 
    1285             :   {
    1286             :     // Fast object, all inobject properties.
    1287             :     int inobject_properties = arraysize(names) * 2;
    1288           4 :     Handle<Map> map = Map::Create(isolate, inobject_properties);
    1289           4 :     Handle<JSObject> object = factory->NewJSObjectFromMap(map);
    1290             :     AddProperties(object, names, arraysize(names), values, arraysize(values),
    1291           4 :                   rand_gen.NextInt());
    1292           4 :     CHECK_EQ(JS_OBJECT_TYPE, object->map()->instance_type());
    1293           4 :     CHECK_EQ(inobject_properties, object->map()->GetInObjectProperties());
    1294           4 :     CHECK(!object->map()->is_dictionary_map());
    1295           4 :     objects.push_back(object);
    1296             :   }
    1297             : 
    1298             :   {
    1299             :     // Fast object, half inobject properties.
    1300             :     int inobject_properties = arraysize(names) / 2;
    1301           4 :     Handle<Map> map = Map::Create(isolate, inobject_properties);
    1302           4 :     Handle<JSObject> object = factory->NewJSObjectFromMap(map);
    1303             :     AddProperties(object, names, arraysize(names), values, arraysize(values),
    1304           4 :                   rand_gen.NextInt());
    1305           4 :     CHECK_EQ(JS_OBJECT_TYPE, object->map()->instance_type());
    1306           4 :     CHECK_EQ(inobject_properties, object->map()->GetInObjectProperties());
    1307           4 :     CHECK(!object->map()->is_dictionary_map());
    1308           4 :     objects.push_back(object);
    1309             :   }
    1310             : 
    1311             :   {
    1312             :     // Dictionary mode object.
    1313             :     Handle<JSFunction> function =
    1314           4 :         factory->NewFunctionForTest(factory->empty_string());
    1315           4 :     Handle<JSObject> object = factory->NewJSObject(function);
    1316             :     AddProperties(object, names, arraysize(names), values, arraysize(values),
    1317           4 :                   rand_gen.NextInt());
    1318           4 :     JSObject::NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0, "test");
    1319             : 
    1320           4 :     JSObject::AddProperty(isolate, object, deleted_property_name, object, NONE);
    1321           8 :     CHECK(JSObject::DeleteProperty(object, deleted_property_name,
    1322             :                                    LanguageMode::kSloppy)
    1323             :               .FromJust());
    1324             : 
    1325           4 :     CHECK_EQ(JS_OBJECT_TYPE, object->map()->instance_type());
    1326           4 :     CHECK(object->map()->is_dictionary_map());
    1327           4 :     objects.push_back(object);
    1328             :   }
    1329             : 
    1330             :   {
    1331             :     // Global object.
    1332           4 :     Handle<JSGlobalObject> object = isolate->global_object();
    1333           4 :     AddProperties(object, names, arraysize(names), values, arraysize(values),
    1334           4 :                   rand_gen.NextInt());
    1335             : 
    1336           4 :     JSObject::AddProperty(isolate, object, deleted_property_name, object, NONE);
    1337           8 :     CHECK(JSObject::DeleteProperty(object, deleted_property_name,
    1338             :                                    LanguageMode::kSloppy)
    1339             :               .FromJust());
    1340             : 
    1341           4 :     CHECK_EQ(JS_GLOBAL_OBJECT_TYPE, object->map()->instance_type());
    1342           4 :     CHECK(object->map()->is_dictionary_map());
    1343           4 :     objects.push_back(object);
    1344             :   }
    1345             : 
    1346             :   // TODO(ishell): test proxy and interceptors when they are supported.
    1347             : 
    1348             :   {
    1349          24 :     for (Handle<JSObject> object : objects) {
    1350         700 :       for (size_t name_index = 0; name_index < arraysize(names); name_index++) {
    1351         340 :         Handle<Name> name = names[name_index];
    1352             :         Handle<Object> expected_value =
    1353         680 :             JSReceiver::GetProperty(isolate, object, name).ToHandleChecked();
    1354         680 :         Handle<Object> value = ft.Call(object, name).ToHandleChecked();
    1355         340 :         CHECK(expected_value->SameValue(*value));
    1356             :       }
    1357             :     }
    1358             :   }
    1359             : 
    1360             :   {
    1361             :     Handle<Name> non_existing_names[] = {
    1362             :         factory->NewSymbol(),
    1363             :         factory->InternalizeUtf8String("ne_a"),
    1364             :         factory->InternalizeUtf8String("ne_bb"),
    1365             :         factory->NewPrivateSymbol(),
    1366             :         factory->InternalizeUtf8String("ne_ccc"),
    1367             :         factory->InternalizeUtf8String("ne_dddd"),
    1368             :         deleted_property_name,
    1369          28 :     };
    1370          24 :     for (Handle<JSObject> object : objects) {
    1371         300 :       for (size_t key_index = 0; key_index < arraysize(non_existing_names);
    1372             :            key_index++) {
    1373         140 :         Handle<Name> name = non_existing_names[key_index];
    1374             :         Handle<Object> expected_value =
    1375         280 :             JSReceiver::GetProperty(isolate, object, name).ToHandleChecked();
    1376         140 :         CHECK(expected_value->IsUndefined(isolate));
    1377         280 :         Handle<Object> value = ft.Call(object, name).ToHandleChecked();
    1378         140 :         CHECK_EQ(*not_found_symbol, *value);
    1379             :       }
    1380             :     }
    1381             :   }
    1382             : 
    1383             :   {
    1384             :     Handle<JSFunction> function =
    1385           4 :         factory->NewFunctionForTest(factory->empty_string());
    1386           4 :     Handle<JSProxy> object = factory->NewJSProxy(function, objects[0]);
    1387           4 :     CHECK_EQ(JS_PROXY_TYPE, object->map()->instance_type());
    1388           8 :     Handle<Object> value = ft.Call(object, names[0]).ToHandleChecked();
    1389             :     // Proxies are not supported yet.
    1390           4 :     CHECK_EQ(*bailout_symbol, *value);
    1391             :   }
    1392             : 
    1393             :   {
    1394           4 :     Handle<JSObject> object = isolate->global_proxy();
    1395           4 :     CHECK_EQ(JS_GLOBAL_PROXY_TYPE, object->map()->instance_type());
    1396             :     // Global proxies are not supported yet.
    1397           8 :     Handle<Object> value = ft.Call(object, names[0]).ToHandleChecked();
    1398           4 :     CHECK_EQ(*bailout_symbol, *value);
    1399             :   }
    1400           4 : }
    1401             : 
    1402             : namespace {
    1403             : 
    1404             : void AddElement(Handle<JSObject> object, uint32_t index, Handle<Object> value,
    1405             :                 PropertyAttributes attributes = NONE) {
    1406          24 :   JSObject::AddDataElement(object, index, value, attributes);
    1407             : }
    1408             : 
    1409             : }  // namespace
    1410             : 
    1411       26643 : TEST(TryLookupElement) {
    1412             :   Isolate* isolate(CcTest::InitIsolateOnce());
    1413             : 
    1414             :   const int kNumParams = 3;
    1415           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    1416           4 :   CodeStubAssembler m(asm_tester.state());
    1417             : 
    1418             :   enum Result { kFound, kAbsent, kNotFound, kBailout };
    1419             :   {
    1420           4 :     Node* object = m.Parameter(0);
    1421          12 :     Node* index = m.SmiUntag(m.Parameter(1));
    1422           4 :     Node* expected_result = m.Parameter(2);
    1423             : 
    1424           4 :     Label passed(&m), failed(&m);
    1425           4 :     Label if_found(&m), if_not_found(&m), if_bailout(&m), if_absent(&m);
    1426             : 
    1427           8 :     Node* map = m.LoadMap(object);
    1428           8 :     Node* instance_type = m.LoadMapInstanceType(map);
    1429             : 
    1430           4 :     m.TryLookupElement(object, map, instance_type, index, &if_found, &if_absent,
    1431           4 :                        &if_not_found, &if_bailout);
    1432             : 
    1433           4 :     m.BIND(&if_found);
    1434           8 :     m.Branch(m.WordEqual(expected_result, m.SmiConstant(Smi::FromInt(kFound))),
    1435           4 :              &passed, &failed);
    1436             : 
    1437           4 :     m.BIND(&if_absent);
    1438           8 :     m.Branch(m.WordEqual(expected_result, m.SmiConstant(Smi::FromInt(kAbsent))),
    1439           4 :              &passed, &failed);
    1440             : 
    1441           4 :     m.BIND(&if_not_found);
    1442           4 :     m.Branch(
    1443           8 :         m.WordEqual(expected_result, m.SmiConstant(Smi::FromInt(kNotFound))),
    1444           4 :         &passed, &failed);
    1445             : 
    1446           4 :     m.BIND(&if_bailout);
    1447           4 :     m.Branch(
    1448           8 :         m.WordEqual(expected_result, m.SmiConstant(Smi::FromInt(kBailout))),
    1449           4 :         &passed, &failed);
    1450             : 
    1451           4 :     m.BIND(&passed);
    1452           8 :     m.Return(m.BooleanConstant(true));
    1453             : 
    1454           4 :     m.BIND(&failed);
    1455           8 :     m.Return(m.BooleanConstant(false));
    1456             :   }
    1457             : 
    1458           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    1459             : 
    1460             :   Factory* factory = isolate->factory();
    1461             :   Handle<Object> smi0(Smi::kZero, isolate);
    1462             :   Handle<Object> smi1(Smi::FromInt(1), isolate);
    1463             :   Handle<Object> smi7(Smi::FromInt(7), isolate);
    1464             :   Handle<Object> smi13(Smi::FromInt(13), isolate);
    1465             :   Handle<Object> smi42(Smi::FromInt(42), isolate);
    1466             : 
    1467             :   Handle<Object> expect_found(Smi::FromInt(kFound), isolate);
    1468             :   Handle<Object> expect_absent(Smi::FromInt(kAbsent), isolate);
    1469             :   Handle<Object> expect_not_found(Smi::FromInt(kNotFound), isolate);
    1470             :   Handle<Object> expect_bailout(Smi::FromInt(kBailout), isolate);
    1471             : 
    1472             : #define CHECK_FOUND(object, index)                         \
    1473             :   CHECK(JSReceiver::HasElement(object, index).FromJust()); \
    1474             :   ft.CheckTrue(object, smi##index, expect_found);
    1475             : 
    1476             : #define CHECK_NOT_FOUND(object, index)                      \
    1477             :   CHECK(!JSReceiver::HasElement(object, index).FromJust()); \
    1478             :   ft.CheckTrue(object, smi##index, expect_not_found);
    1479             : 
    1480             : #define CHECK_ABSENT(object, index)                                        \
    1481             :   {                                                                        \
    1482             :     bool success;                                                          \
    1483             :     Handle<Smi> smi(Smi::FromInt(index), isolate);                         \
    1484             :     LookupIterator it =                                                    \
    1485             :         LookupIterator::PropertyOrElement(isolate, object, smi, &success); \
    1486             :     CHECK(success);                                                        \
    1487             :     CHECK(!JSReceiver::HasProperty(&it).FromJust());                       \
    1488             :     ft.CheckTrue(object, smi, expect_absent);                              \
    1489             :   }
    1490             : 
    1491             :   {
    1492             :     Handle<JSArray> object = factory->NewJSArray(0, PACKED_SMI_ELEMENTS);
    1493             :     AddElement(object, 0, smi0);
    1494             :     AddElement(object, 1, smi0);
    1495           4 :     CHECK_EQ(PACKED_SMI_ELEMENTS, object->map()->elements_kind());
    1496             : 
    1497          12 :     CHECK_FOUND(object, 0);
    1498          12 :     CHECK_FOUND(object, 1);
    1499          12 :     CHECK_NOT_FOUND(object, 7);
    1500          12 :     CHECK_NOT_FOUND(object, 13);
    1501          12 :     CHECK_NOT_FOUND(object, 42);
    1502             :   }
    1503             : 
    1504             :   {
    1505             :     Handle<JSArray> object = factory->NewJSArray(0, HOLEY_SMI_ELEMENTS);
    1506             :     AddElement(object, 0, smi0);
    1507             :     AddElement(object, 13, smi0);
    1508           4 :     CHECK_EQ(HOLEY_SMI_ELEMENTS, object->map()->elements_kind());
    1509             : 
    1510          12 :     CHECK_FOUND(object, 0);
    1511          12 :     CHECK_NOT_FOUND(object, 1);
    1512          12 :     CHECK_NOT_FOUND(object, 7);
    1513          12 :     CHECK_FOUND(object, 13);
    1514          12 :     CHECK_NOT_FOUND(object, 42);
    1515             :   }
    1516             : 
    1517             :   {
    1518             :     Handle<JSArray> object = factory->NewJSArray(0, PACKED_ELEMENTS);
    1519             :     AddElement(object, 0, smi0);
    1520             :     AddElement(object, 1, smi0);
    1521           4 :     CHECK_EQ(PACKED_ELEMENTS, object->map()->elements_kind());
    1522             : 
    1523          12 :     CHECK_FOUND(object, 0);
    1524          12 :     CHECK_FOUND(object, 1);
    1525          12 :     CHECK_NOT_FOUND(object, 7);
    1526          12 :     CHECK_NOT_FOUND(object, 13);
    1527          12 :     CHECK_NOT_FOUND(object, 42);
    1528             :   }
    1529             : 
    1530             :   {
    1531             :     Handle<JSArray> object = factory->NewJSArray(0, HOLEY_ELEMENTS);
    1532             :     AddElement(object, 0, smi0);
    1533             :     AddElement(object, 13, smi0);
    1534           4 :     CHECK_EQ(HOLEY_ELEMENTS, object->map()->elements_kind());
    1535             : 
    1536          12 :     CHECK_FOUND(object, 0);
    1537          12 :     CHECK_NOT_FOUND(object, 1);
    1538          12 :     CHECK_NOT_FOUND(object, 7);
    1539          12 :     CHECK_FOUND(object, 13);
    1540          12 :     CHECK_NOT_FOUND(object, 42);
    1541             :   }
    1542             : 
    1543             :   {
    1544           4 :     Handle<JSTypedArray> object = factory->NewJSTypedArray(INT32_ELEMENTS, 2);
    1545           4 :     Local<v8::ArrayBuffer> buffer = Utils::ToLocal(object->GetBuffer());
    1546             : 
    1547           4 :     CHECK_EQ(INT32_ELEMENTS, object->map()->elements_kind());
    1548             : 
    1549          12 :     CHECK_FOUND(object, 0);
    1550          12 :     CHECK_FOUND(object, 1);
    1551          12 :     CHECK_ABSENT(object, -10);
    1552          12 :     CHECK_ABSENT(object, 13);
    1553          12 :     CHECK_ABSENT(object, 42);
    1554             : 
    1555           4 :     v8::ArrayBuffer::Contents contents = buffer->Externalize();
    1556           4 :     buffer->Detach();
    1557             :     isolate->array_buffer_allocator()->Free(contents.Data(),
    1558           4 :                                             contents.ByteLength());
    1559             : 
    1560          12 :     CHECK_ABSENT(object, 0);
    1561          12 :     CHECK_ABSENT(object, 1);
    1562          12 :     CHECK_ABSENT(object, -10);
    1563          12 :     CHECK_ABSENT(object, 13);
    1564          12 :     CHECK_ABSENT(object, 42);
    1565             :   }
    1566             : 
    1567             :   {
    1568           4 :     Handle<JSFunction> constructor = isolate->string_function();
    1569           4 :     Handle<JSObject> object = factory->NewJSObject(constructor);
    1570           4 :     Handle<String> str = factory->InternalizeUtf8String("ab");
    1571           8 :     Handle<JSValue>::cast(object)->set_value(*str);
    1572             :     AddElement(object, 13, smi0);
    1573           4 :     CHECK_EQ(FAST_STRING_WRAPPER_ELEMENTS, object->map()->elements_kind());
    1574             : 
    1575          12 :     CHECK_FOUND(object, 0);
    1576          12 :     CHECK_FOUND(object, 1);
    1577          12 :     CHECK_NOT_FOUND(object, 7);
    1578          12 :     CHECK_FOUND(object, 13);
    1579          12 :     CHECK_NOT_FOUND(object, 42);
    1580             :   }
    1581             : 
    1582             :   {
    1583           4 :     Handle<JSFunction> constructor = isolate->string_function();
    1584           4 :     Handle<JSObject> object = factory->NewJSObject(constructor);
    1585           4 :     Handle<String> str = factory->InternalizeUtf8String("ab");
    1586           8 :     Handle<JSValue>::cast(object)->set_value(*str);
    1587             :     AddElement(object, 13, smi0);
    1588           4 :     JSObject::NormalizeElements(object);
    1589           4 :     CHECK_EQ(SLOW_STRING_WRAPPER_ELEMENTS, object->map()->elements_kind());
    1590             : 
    1591          12 :     CHECK_FOUND(object, 0);
    1592          12 :     CHECK_FOUND(object, 1);
    1593          12 :     CHECK_NOT_FOUND(object, 7);
    1594          12 :     CHECK_FOUND(object, 13);
    1595          12 :     CHECK_NOT_FOUND(object, 42);
    1596             :   }
    1597             : 
    1598             : // TODO(ishell): uncomment once NO_ELEMENTS kind is supported.
    1599             : //  {
    1600             : //    Handle<Map> map = Map::Create(isolate, 0);
    1601             : //    map->set_elements_kind(NO_ELEMENTS);
    1602             : //    Handle<JSObject> object = factory->NewJSObjectFromMap(map);
    1603             : //    CHECK_EQ(NO_ELEMENTS, object->map()->elements_kind());
    1604             : //
    1605             : //    CHECK_NOT_FOUND(object, 0);
    1606             : //    CHECK_NOT_FOUND(object, 1);
    1607             : //    CHECK_NOT_FOUND(object, 7);
    1608             : //    CHECK_NOT_FOUND(object, 13);
    1609             : //    CHECK_NOT_FOUND(object, 42);
    1610             : //  }
    1611             : 
    1612             : #undef CHECK_FOUND
    1613             : #undef CHECK_NOT_FOUND
    1614             : 
    1615             :   {
    1616             :     Handle<JSArray> handler = factory->NewJSArray(0);
    1617             :     Handle<JSFunction> function =
    1618           4 :         factory->NewFunctionForTest(factory->empty_string());
    1619           4 :     Handle<JSProxy> object = factory->NewJSProxy(function, handler);
    1620           4 :     CHECK_EQ(JS_PROXY_TYPE, object->map()->instance_type());
    1621           4 :     ft.CheckTrue(object, smi0, expect_bailout);
    1622             :   }
    1623             : 
    1624             :   {
    1625           4 :     Handle<JSObject> object = isolate->global_object();
    1626           4 :     CHECK_EQ(JS_GLOBAL_OBJECT_TYPE, object->map()->instance_type());
    1627           4 :     ft.CheckTrue(object, smi0, expect_bailout);
    1628             :   }
    1629             : 
    1630             :   {
    1631           4 :     Handle<JSObject> object = isolate->global_proxy();
    1632           4 :     CHECK_EQ(JS_GLOBAL_PROXY_TYPE, object->map()->instance_type());
    1633           4 :     ft.CheckTrue(object, smi0, expect_bailout);
    1634             :   }
    1635           4 : }
    1636             : 
    1637       26643 : TEST(AllocateJSObjectFromMap) {
    1638             :   Isolate* isolate(CcTest::InitIsolateOnce());
    1639             :   Factory* factory = isolate->factory();
    1640             : 
    1641             :   const int kNumParams = 3;
    1642           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    1643           4 :   CodeStubAssembler m(asm_tester.state());
    1644             : 
    1645             :   {
    1646           4 :     Node* map = m.Parameter(0);
    1647           4 :     Node* properties = m.Parameter(1);
    1648           4 :     Node* elements = m.Parameter(2);
    1649             : 
    1650           4 :     Node* result = m.AllocateJSObjectFromMap(map, properties, elements);
    1651             : 
    1652           4 :     m.Return(result);
    1653             :   }
    1654             : 
    1655           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    1656             : 
    1657             :   Handle<Map> maps[] = {
    1658           8 :       handle(isolate->object_function()->initial_map(), isolate),
    1659           8 :       handle(isolate->array_function()->initial_map(), isolate),
    1660           8 :   };
    1661             : 
    1662             :   {
    1663             :     Handle<FixedArray> empty_fixed_array = factory->empty_fixed_array();
    1664             :     Handle<PropertyArray> empty_property_array =
    1665             :         factory->empty_property_array();
    1666          20 :     for (size_t i = 0; i < arraysize(maps); i++) {
    1667           8 :       Handle<Map> map = maps[i];
    1668             :       Handle<JSObject> result = Handle<JSObject>::cast(
    1669          16 :           ft.Call(map, empty_fixed_array, empty_fixed_array).ToHandleChecked());
    1670           8 :       CHECK_EQ(result->map(), *map);
    1671          16 :       CHECK_EQ(result->property_array(), *empty_property_array);
    1672           8 :       CHECK_EQ(result->elements(), *empty_fixed_array);
    1673           8 :       CHECK(result->HasFastProperties());
    1674             : #ifdef VERIFY_HEAP
    1675             :       isolate->heap()->Verify();
    1676             : #endif
    1677             :     }
    1678             :   }
    1679             : 
    1680             :   {
    1681             :     // TODO(cbruni): handle in-object properties
    1682             :     Handle<JSObject> object = Handle<JSObject>::cast(
    1683             :         v8::Utils::OpenHandle(*CompileRun("var object = {a:1,b:2, 1:1, 2:2}; "
    1684             :                                           "object")));
    1685             :     JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, 0,
    1686           4 :                                   "Normalize");
    1687             :     Handle<JSObject> result = Handle<JSObject>::cast(
    1688           8 :         ft.Call(handle(object->map(), isolate),
    1689           8 :                 handle(object->property_dictionary(), isolate),
    1690           4 :                 handle(object->elements(), isolate))
    1691             :             .ToHandleChecked());
    1692           4 :     CHECK_EQ(result->map(), object->map());
    1693          12 :     CHECK_EQ(result->property_dictionary(), object->property_dictionary());
    1694           4 :     CHECK(!result->HasFastProperties());
    1695             : #ifdef VERIFY_HEAP
    1696             :     isolate->heap()->Verify();
    1697             : #endif
    1698             :   }
    1699             : #undef VERIFY
    1700           4 : }
    1701             : 
    1702       26643 : TEST(AllocateNameDictionary) {
    1703             :   Isolate* isolate(CcTest::InitIsolateOnce());
    1704             : 
    1705             :   const int kNumParams = 1;
    1706           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    1707           4 :   CodeStubAssembler m(asm_tester.state());
    1708             : 
    1709             :   {
    1710           4 :     Node* capacity = m.Parameter(0);
    1711           8 :     Node* result = m.AllocateNameDictionary(m.SmiUntag(capacity));
    1712           4 :     m.Return(result);
    1713             :   }
    1714             : 
    1715           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    1716             : 
    1717             :   {
    1718         324 :     for (int i = 0; i < 256; i = i * 1.1 + 1) {
    1719             :       Handle<HeapObject> result = Handle<HeapObject>::cast(
    1720         320 :           ft.Call(handle(Smi::FromInt(i), isolate)).ToHandleChecked());
    1721         160 :       Handle<NameDictionary> dict = NameDictionary::New(isolate, i);
    1722             :       // Both dictionaries should be memory equal.
    1723         160 :       int size = dict->Size();
    1724         480 :       CHECK_EQ(0, memcmp(reinterpret_cast<void*>(dict->address()),
    1725             :                          reinterpret_cast<void*>(result->address()), size));
    1726             :     }
    1727             :   }
    1728           4 : }
    1729             : 
    1730       26643 : TEST(PopAndReturnConstant) {
    1731             :   Isolate* isolate(CcTest::InitIsolateOnce());
    1732             : 
    1733             :   const int kNumParams = 4;
    1734             :   const int kNumProgrammaticParams = 2;
    1735           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams - kNumProgrammaticParams);
    1736           4 :   CodeStubAssembler m(asm_tester.state());
    1737             : 
    1738             :   // Call a function that return |kNumProgramaticParams| parameters in addition
    1739             :   // to those specified by the static descriptor. |kNumProgramaticParams| is
    1740             :   // specified as a constant.
    1741           8 :   m.PopAndReturn(m.Int32Constant(kNumProgrammaticParams),
    1742          12 :                  m.SmiConstant(Smi::FromInt(1234)));
    1743             : 
    1744           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    1745             :   Handle<Object> result;
    1746         804 :   for (int test_count = 0; test_count < 100; ++test_count) {
    1747         800 :     result = ft.Call(isolate->factory()->undefined_value(),
    1748             :                      Handle<Smi>(Smi::FromInt(1234), isolate),
    1749             :                      isolate->factory()->undefined_value(),
    1750         400 :                      isolate->factory()->undefined_value())
    1751             :                  .ToHandleChecked();
    1752         400 :     CHECK_EQ(1234, Handle<Smi>::cast(result)->value());
    1753             :   }
    1754           4 : }
    1755             : 
    1756       26643 : TEST(PopAndReturnVariable) {
    1757             :   Isolate* isolate(CcTest::InitIsolateOnce());
    1758             : 
    1759             :   const int kNumParams = 4;
    1760             :   const int kNumProgrammaticParams = 2;
    1761           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams - kNumProgrammaticParams);
    1762           4 :   CodeStubAssembler m(asm_tester.state());
    1763             : 
    1764             :   // Call a function that return |kNumProgramaticParams| parameters in addition
    1765             :   // to those specified by the static descriptor. |kNumProgramaticParams| is
    1766             :   // passed in as a parameter to the function so that it can't be recongized as
    1767             :   // a constant.
    1768          16 :   m.PopAndReturn(m.SmiUntag(m.Parameter(1)), m.SmiConstant(Smi::FromInt(1234)));
    1769             : 
    1770           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    1771             :   Handle<Object> result;
    1772         804 :   for (int test_count = 0; test_count < 100; ++test_count) {
    1773         800 :     result = ft.Call(isolate->factory()->undefined_value(),
    1774             :                      Handle<Smi>(Smi::FromInt(1234), isolate),
    1775             :                      isolate->factory()->undefined_value(),
    1776         400 :                      Handle<Smi>(Smi::FromInt(kNumProgrammaticParams), isolate))
    1777             :                  .ToHandleChecked();
    1778         400 :     CHECK_EQ(1234, Handle<Smi>::cast(result)->value());
    1779             :   }
    1780           4 : }
    1781             : 
    1782       26643 : TEST(OneToTwoByteStringCopy) {
    1783             :   Isolate* isolate(CcTest::InitIsolateOnce());
    1784             : 
    1785             :   const int kNumParams = 2;
    1786           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    1787           4 :   CodeStubAssembler m(asm_tester.state());
    1788             : 
    1789           4 :   m.CopyStringCharacters(m.Parameter(0), m.Parameter(1), m.IntPtrConstant(0),
    1790             :                          m.IntPtrConstant(0), m.IntPtrConstant(5),
    1791           4 :                          String::ONE_BYTE_ENCODING, String::TWO_BYTE_ENCODING);
    1792           8 :   m.Return(m.SmiConstant(Smi::FromInt(0)));
    1793             : 
    1794           4 :   Handle<String> string1 = isolate->factory()->InternalizeUtf8String("abcde");
    1795           4 :   uc16 array[] = {1000, 1001, 1002, 1003, 1004};
    1796             :   Vector<const uc16> str(array);
    1797             :   Handle<String> string2 =
    1798           8 :       isolate->factory()->NewStringFromTwoByte(str).ToHandleChecked();
    1799           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    1800           4 :   ft.Call(string1, string2);
    1801             :   DisallowHeapAllocation no_gc;
    1802          12 :   CHECK_EQ(Handle<SeqOneByteString>::cast(string1)->GetChars(no_gc)[0],
    1803             :            Handle<SeqTwoByteString>::cast(string2)->GetChars(no_gc)[0]);
    1804           8 :   CHECK_EQ(Handle<SeqOneByteString>::cast(string1)->GetChars(no_gc)[1],
    1805             :            Handle<SeqTwoByteString>::cast(string2)->GetChars(no_gc)[1]);
    1806           8 :   CHECK_EQ(Handle<SeqOneByteString>::cast(string1)->GetChars(no_gc)[2],
    1807             :            Handle<SeqTwoByteString>::cast(string2)->GetChars(no_gc)[2]);
    1808           8 :   CHECK_EQ(Handle<SeqOneByteString>::cast(string1)->GetChars(no_gc)[3],
    1809             :            Handle<SeqTwoByteString>::cast(string2)->GetChars(no_gc)[3]);
    1810           8 :   CHECK_EQ(Handle<SeqOneByteString>::cast(string1)->GetChars(no_gc)[4],
    1811             :            Handle<SeqTwoByteString>::cast(string2)->GetChars(no_gc)[4]);
    1812           4 : }
    1813             : 
    1814       26643 : TEST(OneToOneByteStringCopy) {
    1815             :   Isolate* isolate(CcTest::InitIsolateOnce());
    1816             : 
    1817             :   const int kNumParams = 2;
    1818           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    1819           4 :   CodeStubAssembler m(asm_tester.state());
    1820             : 
    1821           4 :   m.CopyStringCharacters(m.Parameter(0), m.Parameter(1), m.IntPtrConstant(0),
    1822             :                          m.IntPtrConstant(0), m.IntPtrConstant(5),
    1823           4 :                          String::ONE_BYTE_ENCODING, String::ONE_BYTE_ENCODING);
    1824           8 :   m.Return(m.SmiConstant(Smi::FromInt(0)));
    1825             : 
    1826           4 :   Handle<String> string1 = isolate->factory()->InternalizeUtf8String("abcde");
    1827           4 :   uint8_t array[] = {100, 101, 102, 103, 104};
    1828             :   Vector<const uint8_t> str(array);
    1829             :   Handle<String> string2 =
    1830           8 :       isolate->factory()->NewStringFromOneByte(str).ToHandleChecked();
    1831           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    1832           4 :   ft.Call(string1, string2);
    1833             :   DisallowHeapAllocation no_gc;
    1834           8 :   CHECK_EQ(Handle<SeqOneByteString>::cast(string1)->GetChars(no_gc)[0],
    1835             :            Handle<SeqOneByteString>::cast(string2)->GetChars(no_gc)[0]);
    1836           4 :   CHECK_EQ(Handle<SeqOneByteString>::cast(string1)->GetChars(no_gc)[1],
    1837             :            Handle<SeqOneByteString>::cast(string2)->GetChars(no_gc)[1]);
    1838           4 :   CHECK_EQ(Handle<SeqOneByteString>::cast(string1)->GetChars(no_gc)[2],
    1839             :            Handle<SeqOneByteString>::cast(string2)->GetChars(no_gc)[2]);
    1840           4 :   CHECK_EQ(Handle<SeqOneByteString>::cast(string1)->GetChars(no_gc)[3],
    1841             :            Handle<SeqOneByteString>::cast(string2)->GetChars(no_gc)[3]);
    1842           4 :   CHECK_EQ(Handle<SeqOneByteString>::cast(string1)->GetChars(no_gc)[4],
    1843             :            Handle<SeqOneByteString>::cast(string2)->GetChars(no_gc)[4]);
    1844           4 : }
    1845             : 
    1846       26643 : TEST(OneToOneByteStringCopyNonZeroStart) {
    1847             :   Isolate* isolate(CcTest::InitIsolateOnce());
    1848             : 
    1849             :   const int kNumParams = 2;
    1850           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    1851           4 :   CodeStubAssembler m(asm_tester.state());
    1852             : 
    1853           4 :   m.CopyStringCharacters(m.Parameter(0), m.Parameter(1), m.IntPtrConstant(0),
    1854             :                          m.IntPtrConstant(3), m.IntPtrConstant(2),
    1855           4 :                          String::ONE_BYTE_ENCODING, String::ONE_BYTE_ENCODING);
    1856           8 :   m.Return(m.SmiConstant(Smi::FromInt(0)));
    1857             : 
    1858           4 :   Handle<String> string1 = isolate->factory()->InternalizeUtf8String("abcde");
    1859           4 :   uint8_t array[] = {100, 101, 102, 103, 104};
    1860             :   Vector<const uint8_t> str(array);
    1861             :   Handle<String> string2 =
    1862           8 :       isolate->factory()->NewStringFromOneByte(str).ToHandleChecked();
    1863           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    1864           4 :   ft.Call(string1, string2);
    1865             :   DisallowHeapAllocation no_gc;
    1866           8 :   CHECK_EQ(Handle<SeqOneByteString>::cast(string1)->GetChars(no_gc)[0],
    1867             :            Handle<SeqOneByteString>::cast(string2)->GetChars(no_gc)[3]);
    1868           4 :   CHECK_EQ(Handle<SeqOneByteString>::cast(string1)->GetChars(no_gc)[1],
    1869             :            Handle<SeqOneByteString>::cast(string2)->GetChars(no_gc)[4]);
    1870           8 :   CHECK_EQ(100, Handle<SeqOneByteString>::cast(string2)->GetChars(no_gc)[0]);
    1871           8 :   CHECK_EQ(101, Handle<SeqOneByteString>::cast(string2)->GetChars(no_gc)[1]);
    1872           8 :   CHECK_EQ(102, Handle<SeqOneByteString>::cast(string2)->GetChars(no_gc)[2]);
    1873           4 : }
    1874             : 
    1875       26643 : TEST(TwoToTwoByteStringCopy) {
    1876             :   Isolate* isolate(CcTest::InitIsolateOnce());
    1877             : 
    1878             :   const int kNumParams = 2;
    1879           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    1880           4 :   CodeStubAssembler m(asm_tester.state());
    1881             : 
    1882           4 :   m.CopyStringCharacters(m.Parameter(0), m.Parameter(1), m.IntPtrConstant(0),
    1883             :                          m.IntPtrConstant(0), m.IntPtrConstant(5),
    1884           4 :                          String::TWO_BYTE_ENCODING, String::TWO_BYTE_ENCODING);
    1885           8 :   m.Return(m.SmiConstant(Smi::FromInt(0)));
    1886             : 
    1887           4 :   uc16 array1[] = {2000, 2001, 2002, 2003, 2004};
    1888             :   Vector<const uc16> str1(array1);
    1889             :   Handle<String> string1 =
    1890           8 :       isolate->factory()->NewStringFromTwoByte(str1).ToHandleChecked();
    1891           4 :   uc16 array2[] = {1000, 1001, 1002, 1003, 1004};
    1892             :   Vector<const uc16> str2(array2);
    1893             :   Handle<String> string2 =
    1894           8 :       isolate->factory()->NewStringFromTwoByte(str2).ToHandleChecked();
    1895           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    1896           4 :   ft.Call(string1, string2);
    1897             :   DisallowHeapAllocation no_gc;
    1898           8 :   CHECK_EQ(Handle<SeqTwoByteString>::cast(string1)->GetChars(no_gc)[0],
    1899             :            Handle<SeqTwoByteString>::cast(string2)->GetChars(no_gc)[0]);
    1900           4 :   CHECK_EQ(Handle<SeqTwoByteString>::cast(string1)->GetChars(no_gc)[1],
    1901             :            Handle<SeqTwoByteString>::cast(string2)->GetChars(no_gc)[1]);
    1902           4 :   CHECK_EQ(Handle<SeqTwoByteString>::cast(string1)->GetChars(no_gc)[2],
    1903             :            Handle<SeqTwoByteString>::cast(string2)->GetChars(no_gc)[2]);
    1904           4 :   CHECK_EQ(Handle<SeqTwoByteString>::cast(string1)->GetChars(no_gc)[3],
    1905             :            Handle<SeqTwoByteString>::cast(string2)->GetChars(no_gc)[3]);
    1906           4 :   CHECK_EQ(Handle<SeqTwoByteString>::cast(string1)->GetChars(no_gc)[4],
    1907             :            Handle<SeqTwoByteString>::cast(string2)->GetChars(no_gc)[4]);
    1908           4 : }
    1909             : 
    1910       26643 : TEST(Arguments) {
    1911             :   Isolate* isolate(CcTest::InitIsolateOnce());
    1912             : 
    1913             :   const int kNumParams = 4;
    1914           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    1915           4 :   CodeStubAssembler m(asm_tester.state());
    1916             : 
    1917           8 :   CodeStubArguments arguments(&m, m.IntPtrConstant(3));
    1918             : 
    1919             :   CSA_ASSERT(
    1920             :       &m, m.WordEqual(arguments.AtIndex(0), m.SmiConstant(Smi::FromInt(12))));
    1921             :   CSA_ASSERT(
    1922             :       &m, m.WordEqual(arguments.AtIndex(1), m.SmiConstant(Smi::FromInt(13))));
    1923             :   CSA_ASSERT(
    1924             :       &m, m.WordEqual(arguments.AtIndex(2), m.SmiConstant(Smi::FromInt(14))));
    1925             : 
    1926           8 :   arguments.PopAndReturn(arguments.GetReceiver());
    1927             : 
    1928           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    1929           8 :   Handle<Object> result = ft.Call(isolate->factory()->undefined_value(),
    1930             :                                   Handle<Smi>(Smi::FromInt(12), isolate),
    1931             :                                   Handle<Smi>(Smi::FromInt(13), isolate),
    1932           4 :                                   Handle<Smi>(Smi::FromInt(14), isolate))
    1933             :                               .ToHandleChecked();
    1934           4 :   CHECK_EQ(*isolate->factory()->undefined_value(), *result);
    1935           4 : }
    1936             : 
    1937       26643 : TEST(ArgumentsWithSmiConstantIndices) {
    1938             :   Isolate* isolate(CcTest::InitIsolateOnce());
    1939             : 
    1940             :   const int kNumParams = 4;
    1941           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    1942           4 :   CodeStubAssembler m(asm_tester.state());
    1943             : 
    1944           8 :   CodeStubArguments arguments(&m, m.SmiConstant(3), nullptr,
    1945           4 :                               CodeStubAssembler::SMI_PARAMETERS);
    1946             : 
    1947             :   CSA_ASSERT(&m,
    1948             :              m.WordEqual(arguments.AtIndex(m.SmiConstant(0),
    1949             :                                            CodeStubAssembler::SMI_PARAMETERS),
    1950             :                          m.SmiConstant(Smi::FromInt(12))));
    1951             :   CSA_ASSERT(&m,
    1952             :              m.WordEqual(arguments.AtIndex(m.SmiConstant(1),
    1953             :                                            CodeStubAssembler::SMI_PARAMETERS),
    1954             :                          m.SmiConstant(Smi::FromInt(13))));
    1955             :   CSA_ASSERT(&m,
    1956             :              m.WordEqual(arguments.AtIndex(m.SmiConstant(2),
    1957             :                                            CodeStubAssembler::SMI_PARAMETERS),
    1958             :                          m.SmiConstant(Smi::FromInt(14))));
    1959             : 
    1960           8 :   arguments.PopAndReturn(arguments.GetReceiver());
    1961             : 
    1962           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    1963           8 :   Handle<Object> result = ft.Call(isolate->factory()->undefined_value(),
    1964             :                                   Handle<Smi>(Smi::FromInt(12), isolate),
    1965             :                                   Handle<Smi>(Smi::FromInt(13), isolate),
    1966           4 :                                   Handle<Smi>(Smi::FromInt(14), isolate))
    1967             :                               .ToHandleChecked();
    1968           4 :   CHECK_EQ(*isolate->factory()->undefined_value(), *result);
    1969           4 : }
    1970             : 
    1971           0 : TNode<Smi> NonConstantSmi(CodeStubAssembler* m, int value) {
    1972             :   // Generate a SMI with the given value and feed it through a Phi so it can't
    1973             :   // be inferred to be constant.
    1974           0 :   Variable var(m, MachineRepresentation::kTagged, m->SmiConstant(value));
    1975           0 :   Label dummy_done(m);
    1976             :   // Even though the Goto always executes, it will taint the variable and thus
    1977             :   // make it appear non-constant when used later.
    1978           0 :   m->GotoIf(m->Int32Constant(1), &dummy_done);
    1979           0 :   var.Bind(m->SmiConstant(value));
    1980           0 :   m->Goto(&dummy_done);
    1981           0 :   m->BIND(&dummy_done);
    1982             : 
    1983             :   // Ensure that the above hackery actually created a non-constant SMI.
    1984           0 :   Smi smi_constant;
    1985           0 :   CHECK(!m->ToSmiConstant(var.value(), &smi_constant));
    1986             : 
    1987           0 :   return m->UncheckedCast<Smi>(var.value());
    1988             : }
    1989             : 
    1990       26643 : TEST(ArgumentsWithSmiIndices) {
    1991             :   Isolate* isolate(CcTest::InitIsolateOnce());
    1992             : 
    1993             :   const int kNumParams = 4;
    1994           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    1995           4 :   CodeStubAssembler m(asm_tester.state());
    1996             : 
    1997           8 :   CodeStubArguments arguments(&m, m.SmiConstant(3), nullptr,
    1998           4 :                               CodeStubAssembler::SMI_PARAMETERS);
    1999             : 
    2000             :   CSA_ASSERT(&m,
    2001             :              m.WordEqual(arguments.AtIndex(NonConstantSmi(&m, 0),
    2002             :                                            CodeStubAssembler::SMI_PARAMETERS),
    2003             :                          m.SmiConstant(Smi::FromInt(12))));
    2004             :   CSA_ASSERT(&m,
    2005             :              m.WordEqual(arguments.AtIndex(NonConstantSmi(&m, 1),
    2006             :                                            CodeStubAssembler::SMI_PARAMETERS),
    2007             :                          m.SmiConstant(Smi::FromInt(13))));
    2008             :   CSA_ASSERT(&m,
    2009             :              m.WordEqual(arguments.AtIndex(NonConstantSmi(&m, 2),
    2010             :                                            CodeStubAssembler::SMI_PARAMETERS),
    2011             :                          m.SmiConstant(Smi::FromInt(14))));
    2012             : 
    2013           8 :   arguments.PopAndReturn(arguments.GetReceiver());
    2014             : 
    2015           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    2016           8 :   Handle<Object> result = ft.Call(isolate->factory()->undefined_value(),
    2017             :                                   Handle<Smi>(Smi::FromInt(12), isolate),
    2018             :                                   Handle<Smi>(Smi::FromInt(13), isolate),
    2019           4 :                                   Handle<Smi>(Smi::FromInt(14), isolate))
    2020             :                               .ToHandleChecked();
    2021           4 :   CHECK_EQ(*isolate->factory()->undefined_value(), *result);
    2022           4 : }
    2023             : 
    2024       26643 : TEST(ArgumentsForEach) {
    2025             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2026             : 
    2027             :   const int kNumParams = 4;
    2028           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    2029           4 :   CodeStubAssembler m(asm_tester.state());
    2030             : 
    2031           8 :   CodeStubArguments arguments(&m, m.IntPtrConstant(3));
    2032             : 
    2033             :   TVariable<Smi> sum(&m);
    2034           8 :   CodeAssemblerVariableList list({&sum}, m.zone());
    2035             : 
    2036           4 :   sum = m.SmiConstant(0);
    2037             : 
    2038          16 :   arguments.ForEach(list, [&m, &sum](Node* arg) {
    2039           4 :     sum = m.SmiAdd(sum.value(), m.CAST(arg));
    2040           8 :   });
    2041             : 
    2042           4 :   arguments.PopAndReturn(sum.value());
    2043             : 
    2044           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    2045           8 :   Handle<Object> result = ft.Call(isolate->factory()->undefined_value(),
    2046             :                                   Handle<Smi>(Smi::FromInt(12), isolate),
    2047             :                                   Handle<Smi>(Smi::FromInt(13), isolate),
    2048           4 :                                   Handle<Smi>(Smi::FromInt(14), isolate))
    2049             :                               .ToHandleChecked();
    2050           4 :   CHECK_EQ(Smi::FromInt(12 + 13 + 14), *result);
    2051           4 : }
    2052             : 
    2053       26643 : TEST(IsDebugActive) {
    2054             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2055             : 
    2056             :   const int kNumParams = 1;
    2057           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    2058           4 :   CodeStubAssembler m(asm_tester.state());
    2059             : 
    2060           4 :   Label if_active(&m), if_not_active(&m);
    2061             : 
    2062           8 :   m.Branch(m.IsDebugActive(), &if_active, &if_not_active);
    2063           4 :   m.BIND(&if_active);
    2064           8 :   m.Return(m.TrueConstant());
    2065           4 :   m.BIND(&if_not_active);
    2066           8 :   m.Return(m.FalseConstant());
    2067             : 
    2068           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    2069           4 :   CHECK(!isolate->debug()->is_active());
    2070             :   Handle<Object> result =
    2071           8 :       ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
    2072           4 :   CHECK_EQ(ReadOnlyRoots(isolate).false_value(), *result);
    2073             : 
    2074             :   bool* debug_is_active = reinterpret_cast<bool*>(
    2075           8 :       ExternalReference::debug_is_active_address(isolate).address());
    2076             : 
    2077             :   // Cheat to enable debug (TODO: do this properly).
    2078           4 :   *debug_is_active = true;
    2079             : 
    2080           8 :   result = ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
    2081           4 :   CHECK_EQ(ReadOnlyRoots(isolate).true_value(), *result);
    2082             : 
    2083             :   // Reset debug mode.
    2084           4 :   *debug_is_active = false;
    2085           4 : }
    2086             : 
    2087          36 : class AppendJSArrayCodeStubAssembler : public CodeStubAssembler {
    2088             :  public:
    2089             :   AppendJSArrayCodeStubAssembler(compiler::CodeAssemblerState* state,
    2090             :                                  ElementsKind kind)
    2091          36 :       : CodeStubAssembler(state), kind_(kind) {}
    2092             : 
    2093          36 :   void TestAppendJSArrayImpl(Isolate* isolate, CodeAssemblerTester* csa_tester,
    2094             :                              Object o1, Object o2, Object o3, Object o4,
    2095             :                              int initial_size, int result_size) {
    2096             :     Handle<JSArray> array = isolate->factory()->NewJSArray(
    2097          36 :         kind_, 2, initial_size, INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
    2098          72 :     Object::SetElement(isolate, array, 0, Handle<Smi>(Smi::FromInt(1), isolate),
    2099          36 :                        kDontThrow)
    2100             :         .Check();
    2101          72 :     Object::SetElement(isolate, array, 1, Handle<Smi>(Smi::FromInt(2), isolate),
    2102          36 :                        kDontThrow)
    2103             :         .Check();
    2104         108 :     CodeStubArguments args(this, IntPtrConstant(kNumParams));
    2105             :     TVariable<IntPtrT> arg_index(this);
    2106          36 :     Label bailout(this);
    2107          36 :     arg_index = IntPtrConstant(0);
    2108         108 :     Node* length = BuildAppendJSArray(kind_, HeapConstant(array), &args,
    2109          72 :                                       &arg_index, &bailout);
    2110          36 :     Return(length);
    2111             : 
    2112          36 :     BIND(&bailout);
    2113         108 :     Return(SmiTag(IntPtrAdd(arg_index.value(), IntPtrConstant(2))));
    2114             : 
    2115          36 :     FunctionTester ft(csa_tester->GenerateCode(), kNumParams);
    2116             : 
    2117             :     Handle<Object> result =
    2118          72 :         ft.Call(Handle<Object>(o1, isolate), Handle<Object>(o2, isolate),
    2119          36 :                 Handle<Object>(o3, isolate), Handle<Object>(o4, isolate))
    2120             :             .ToHandleChecked();
    2121             : 
    2122          36 :     CHECK_EQ(kind_, array->GetElementsKind());
    2123          36 :     CHECK_EQ(result_size, Handle<Smi>::cast(result)->value());
    2124          36 :     CHECK_EQ(result_size, Smi::ToInt(array->length()));
    2125          72 :     Object obj = *JSObject::GetElement(isolate, array, 2).ToHandleChecked();
    2126          36 :     HeapObject undefined_value = ReadOnlyRoots(isolate).undefined_value();
    2127          72 :     CHECK_EQ(result_size < 3 ? undefined_value : o1, obj);
    2128          72 :     obj = *JSObject::GetElement(isolate, array, 3).ToHandleChecked();
    2129          72 :     CHECK_EQ(result_size < 4 ? undefined_value : o2, obj);
    2130          72 :     obj = *JSObject::GetElement(isolate, array, 4).ToHandleChecked();
    2131          72 :     CHECK_EQ(result_size < 5 ? undefined_value : o3, obj);
    2132          72 :     obj = *JSObject::GetElement(isolate, array, 5).ToHandleChecked();
    2133          72 :     CHECK_EQ(result_size < 6 ? undefined_value : o4, obj);
    2134          36 :   }
    2135             : 
    2136          36 :   static void TestAppendJSArray(Isolate* isolate, ElementsKind kind, Object o1,
    2137             :                                 Object o2, Object o3, Object o4,
    2138             :                                 int initial_size, int result_size) {
    2139          72 :     CodeAssemblerTester asm_tester(isolate, kNumParams);
    2140             :     AppendJSArrayCodeStubAssembler m(asm_tester.state(), kind);
    2141             :     m.TestAppendJSArrayImpl(isolate, &asm_tester, o1, o2, o3, o4, initial_size,
    2142          36 :                             result_size);
    2143          36 :   }
    2144             : 
    2145             :  private:
    2146             :   static const int kNumParams = 4;
    2147             :   ElementsKind kind_;
    2148             : };
    2149             : 
    2150       26643 : TEST(BuildAppendJSArrayFastElement) {
    2151             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2152             :   AppendJSArrayCodeStubAssembler::TestAppendJSArray(
    2153           8 :       isolate, PACKED_ELEMENTS, Smi::FromInt(3), Smi::FromInt(4),
    2154          12 :       Smi::FromInt(5), Smi::FromInt(6), 6, 6);
    2155           4 : }
    2156             : 
    2157       26643 : TEST(BuildAppendJSArrayFastElementGrow) {
    2158             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2159             :   AppendJSArrayCodeStubAssembler::TestAppendJSArray(
    2160           8 :       isolate, PACKED_ELEMENTS, Smi::FromInt(3), Smi::FromInt(4),
    2161          12 :       Smi::FromInt(5), Smi::FromInt(6), 2, 6);
    2162           4 : }
    2163             : 
    2164       26643 : TEST(BuildAppendJSArrayFastSmiElement) {
    2165             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2166             :   AppendJSArrayCodeStubAssembler::TestAppendJSArray(
    2167           8 :       isolate, PACKED_SMI_ELEMENTS, Smi::FromInt(3), Smi::FromInt(4),
    2168          12 :       Smi::FromInt(5), Smi::FromInt(6), 6, 6);
    2169           4 : }
    2170             : 
    2171       26643 : TEST(BuildAppendJSArrayFastSmiElementGrow) {
    2172             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2173             :   AppendJSArrayCodeStubAssembler::TestAppendJSArray(
    2174           8 :       isolate, PACKED_SMI_ELEMENTS, Smi::FromInt(3), Smi::FromInt(4),
    2175          12 :       Smi::FromInt(5), Smi::FromInt(6), 2, 6);
    2176           4 : }
    2177             : 
    2178       26643 : TEST(BuildAppendJSArrayFastSmiElementObject) {
    2179             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2180             :   AppendJSArrayCodeStubAssembler::TestAppendJSArray(
    2181           8 :       isolate, PACKED_SMI_ELEMENTS, Smi::FromInt(3), Smi::FromInt(4),
    2182          16 :       ReadOnlyRoots(isolate).undefined_value(), Smi::FromInt(6), 6, 4);
    2183           4 : }
    2184             : 
    2185       26643 : TEST(BuildAppendJSArrayFastSmiElementObjectGrow) {
    2186             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2187             :   AppendJSArrayCodeStubAssembler::TestAppendJSArray(
    2188           8 :       isolate, PACKED_SMI_ELEMENTS, Smi::FromInt(3), Smi::FromInt(4),
    2189          16 :       ReadOnlyRoots(isolate).undefined_value(), Smi::FromInt(6), 2, 4);
    2190           4 : }
    2191             : 
    2192       26643 : TEST(BuildAppendJSArrayFastDoubleElements) {
    2193             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2194             :   AppendJSArrayCodeStubAssembler::TestAppendJSArray(
    2195           8 :       isolate, PACKED_DOUBLE_ELEMENTS, Smi::FromInt(3), Smi::FromInt(4),
    2196          12 :       Smi::FromInt(5), Smi::FromInt(6), 6, 6);
    2197           4 : }
    2198             : 
    2199       26643 : TEST(BuildAppendJSArrayFastDoubleElementsGrow) {
    2200             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2201             :   AppendJSArrayCodeStubAssembler::TestAppendJSArray(
    2202           8 :       isolate, PACKED_DOUBLE_ELEMENTS, Smi::FromInt(3), Smi::FromInt(4),
    2203          12 :       Smi::FromInt(5), Smi::FromInt(6), 2, 6);
    2204           4 : }
    2205             : 
    2206       26643 : TEST(BuildAppendJSArrayFastDoubleElementsObject) {
    2207             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2208             :   AppendJSArrayCodeStubAssembler::TestAppendJSArray(
    2209           8 :       isolate, PACKED_DOUBLE_ELEMENTS, Smi::FromInt(3), Smi::FromInt(4),
    2210          16 :       ReadOnlyRoots(isolate).undefined_value(), Smi::FromInt(6), 6, 4);
    2211           4 : }
    2212             : 
    2213             : namespace {
    2214             : 
    2215             : template <typename Stub, typename... Args>
    2216             : void Recompile(Args... args) {
    2217             :   Stub stub(args...);
    2218             :   stub.DeleteStubFromCacheForTesting();
    2219             :   stub.GetCode();
    2220             : }
    2221             : 
    2222             : }  // namespace
    2223             : 
    2224           0 : void CustomPromiseHook(v8::PromiseHookType type, v8::Local<v8::Promise> promise,
    2225           0 :                        v8::Local<v8::Value> parentPromise) {}
    2226             : 
    2227       26643 : TEST(IsPromiseHookEnabled) {
    2228             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2229             : 
    2230             :   const int kNumParams = 1;
    2231           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    2232           4 :   CodeStubAssembler m(asm_tester.state());
    2233             : 
    2234           4 :   m.Return(
    2235          16 :       m.SelectBooleanConstant(m.IsPromiseHookEnabledOrHasAsyncEventDelegate()));
    2236             : 
    2237           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    2238             :   Handle<Object> result =
    2239           8 :       ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
    2240           4 :   CHECK_EQ(ReadOnlyRoots(isolate).false_value(), *result);
    2241             : 
    2242           4 :   isolate->SetPromiseHook(CustomPromiseHook);
    2243           8 :   result = ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
    2244           4 :   CHECK_EQ(ReadOnlyRoots(isolate).true_value(), *result);
    2245             : 
    2246           4 :   isolate->SetPromiseHook(nullptr);
    2247           8 :   result = ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
    2248           4 :   CHECK_EQ(ReadOnlyRoots(isolate).false_value(), *result);
    2249           4 : }
    2250             : 
    2251       26643 : TEST(AllocateAndInitJSPromise) {
    2252             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2253             : 
    2254             :   const int kNumParams = 1;
    2255           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    2256             :   PromiseBuiltinsAssembler m(asm_tester.state());
    2257             : 
    2258           4 :   Node* const context = m.Parameter(kNumParams + 2);
    2259           4 :   Node* const promise = m.AllocateAndInitJSPromise(context);
    2260           4 :   m.Return(promise);
    2261             : 
    2262           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    2263             :   Handle<Object> result =
    2264           8 :       ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
    2265           4 :   CHECK(result->IsJSPromise());
    2266           4 : }
    2267             : 
    2268       26643 : TEST(AllocateAndSetJSPromise) {
    2269             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2270             : 
    2271             :   const int kNumParams = 1;
    2272           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    2273             :   PromiseBuiltinsAssembler m(asm_tester.state());
    2274             : 
    2275           4 :   Node* const context = m.Parameter(kNumParams + 2);
    2276             :   Node* const promise = m.AllocateAndSetJSPromise(
    2277           8 :       context, v8::Promise::kRejected, m.SmiConstant(1));
    2278           4 :   m.Return(promise);
    2279             : 
    2280           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    2281             :   Handle<Object> result =
    2282           8 :       ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
    2283           4 :   CHECK(result->IsJSPromise());
    2284             :   Handle<JSPromise> js_promise = Handle<JSPromise>::cast(result);
    2285           4 :   CHECK_EQ(v8::Promise::kRejected, js_promise->status());
    2286           4 :   CHECK_EQ(Smi::FromInt(1), js_promise->result());
    2287           4 :   CHECK(!js_promise->has_handler());
    2288           4 : }
    2289             : 
    2290       26643 : TEST(IsSymbol) {
    2291             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2292             : 
    2293             :   const int kNumParams = 1;
    2294           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    2295           4 :   CodeStubAssembler m(asm_tester.state());
    2296             : 
    2297           4 :   Node* const symbol = m.Parameter(0);
    2298          12 :   m.Return(m.SelectBooleanConstant(m.IsSymbol(symbol)));
    2299             : 
    2300           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    2301             :   Handle<Object> result =
    2302           8 :       ft.Call(isolate->factory()->NewSymbol()).ToHandleChecked();
    2303           4 :   CHECK_EQ(ReadOnlyRoots(isolate).true_value(), *result);
    2304             : 
    2305           8 :   result = ft.Call(isolate->factory()->empty_string()).ToHandleChecked();
    2306           4 :   CHECK_EQ(ReadOnlyRoots(isolate).false_value(), *result);
    2307           4 : }
    2308             : 
    2309       26643 : TEST(IsPrivateSymbol) {
    2310             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2311             : 
    2312             :   const int kNumParams = 1;
    2313           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    2314           4 :   CodeStubAssembler m(asm_tester.state());
    2315             : 
    2316           4 :   Node* const symbol = m.Parameter(0);
    2317          12 :   m.Return(m.SelectBooleanConstant(m.IsPrivateSymbol(symbol)));
    2318             : 
    2319           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    2320             :   Handle<Object> result =
    2321           8 :       ft.Call(isolate->factory()->NewSymbol()).ToHandleChecked();
    2322           4 :   CHECK_EQ(ReadOnlyRoots(isolate).false_value(), *result);
    2323             : 
    2324           8 :   result = ft.Call(isolate->factory()->empty_string()).ToHandleChecked();
    2325           4 :   CHECK_EQ(ReadOnlyRoots(isolate).false_value(), *result);
    2326             : 
    2327           8 :   result = ft.Call(isolate->factory()->NewPrivateSymbol()).ToHandleChecked();
    2328           4 :   CHECK_EQ(ReadOnlyRoots(isolate).true_value(), *result);
    2329           4 : }
    2330             : 
    2331       26643 : TEST(PromiseHasHandler) {
    2332             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2333             : 
    2334             :   const int kNumParams = 1;
    2335           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    2336             :   PromiseBuiltinsAssembler m(asm_tester.state());
    2337             : 
    2338           4 :   Node* const context = m.Parameter(kNumParams + 2);
    2339             :   Node* const promise =
    2340           8 :       m.AllocateAndInitJSPromise(context, m.UndefinedConstant());
    2341          12 :   m.Return(m.SelectBooleanConstant(m.PromiseHasHandler(promise)));
    2342             : 
    2343           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    2344             :   Handle<Object> result =
    2345           8 :       ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
    2346           4 :   CHECK_EQ(ReadOnlyRoots(isolate).false_value(), *result);
    2347           4 : }
    2348             : 
    2349       26643 : TEST(CreatePromiseResolvingFunctionsContext) {
    2350             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2351             : 
    2352             :   const int kNumParams = 1;
    2353           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    2354             :   PromiseBuiltinsAssembler m(asm_tester.state());
    2355             : 
    2356           4 :   Node* const context = m.Parameter(kNumParams + 2);
    2357           8 :   Node* const native_context = m.LoadNativeContext(context);
    2358             :   Node* const promise =
    2359           8 :       m.AllocateAndInitJSPromise(context, m.UndefinedConstant());
    2360             :   Node* const promise_context = m.CreatePromiseResolvingFunctionsContext(
    2361           8 :       promise, m.BooleanConstant(false), native_context);
    2362           4 :   m.Return(promise_context);
    2363             : 
    2364           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    2365             :   Handle<Object> result =
    2366           8 :       ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
    2367           4 :   CHECK(result->IsContext());
    2368             :   Handle<Context> context_js = Handle<Context>::cast(result);
    2369          12 :   CHECK_EQ(isolate->native_context()->scope_info(), context_js->scope_info());
    2370           8 :   CHECK_EQ(ReadOnlyRoots(isolate).the_hole_value(), context_js->extension());
    2371           8 :   CHECK_EQ(*isolate->native_context(), context_js->native_context());
    2372           4 :   CHECK(context_js->get(PromiseBuiltins::kPromiseSlot)->IsJSPromise());
    2373           4 :   CHECK_EQ(ReadOnlyRoots(isolate).false_value(),
    2374             :            context_js->get(PromiseBuiltins::kDebugEventSlot));
    2375           4 : }
    2376             : 
    2377       26643 : TEST(CreatePromiseResolvingFunctions) {
    2378             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2379             : 
    2380             :   const int kNumParams = 1;
    2381           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    2382             :   PromiseBuiltinsAssembler m(asm_tester.state());
    2383             : 
    2384           4 :   Node* const context = m.Parameter(kNumParams + 2);
    2385           8 :   Node* const native_context = m.LoadNativeContext(context);
    2386             :   Node* const promise =
    2387           8 :       m.AllocateAndInitJSPromise(context, m.UndefinedConstant());
    2388             :   Node *resolve, *reject;
    2389           8 :   std::tie(resolve, reject) = m.CreatePromiseResolvingFunctions(
    2390           8 :       promise, m.BooleanConstant(false), native_context);
    2391           8 :   Node* const kSize = m.IntPtrConstant(2);
    2392             :   TNode<FixedArray> const arr =
    2393           4 :       m.Cast(m.AllocateFixedArray(PACKED_ELEMENTS, kSize));
    2394           4 :   m.StoreFixedArrayElement(arr, 0, resolve);
    2395           4 :   m.StoreFixedArrayElement(arr, 1, reject);
    2396           4 :   m.Return(arr);
    2397             : 
    2398           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    2399             :   Handle<Object> result_obj =
    2400           8 :       ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
    2401           4 :   CHECK(result_obj->IsFixedArray());
    2402             :   Handle<FixedArray> result_arr = Handle<FixedArray>::cast(result_obj);
    2403           4 :   CHECK(result_arr->get(0)->IsJSFunction());
    2404           4 :   CHECK(result_arr->get(1)->IsJSFunction());
    2405           4 : }
    2406             : 
    2407       26643 : TEST(NewElementsCapacity) {
    2408             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2409           8 :   CodeAssemblerTester asm_tester(isolate, 1);
    2410           4 :   CodeStubAssembler m(asm_tester.state());
    2411           8 :   m.Return(m.SmiTag(m.CalculateNewElementsCapacity(
    2412          20 :       m.SmiUntag(m.Parameter(0)), CodeStubAssembler::INTPTR_PARAMETERS)));
    2413             : 
    2414           4 :   FunctionTester ft(asm_tester.GenerateCode(), 1);
    2415             :   Handle<Smi> test_value = Handle<Smi>(Smi::FromInt(0), isolate);
    2416           4 :   Handle<Smi> result_obj = ft.CallChecked<Smi>(test_value);
    2417          12 :   CHECK_EQ(
    2418             :       result_obj->value(),
    2419             :       static_cast<int>(JSObject::NewElementsCapacity(test_value->value())));
    2420             :   test_value = Handle<Smi>(Smi::FromInt(1), isolate);
    2421           4 :   result_obj = ft.CallChecked<Smi>(test_value);
    2422          12 :   CHECK_EQ(
    2423             :       result_obj->value(),
    2424             :       static_cast<int>(JSObject::NewElementsCapacity(test_value->value())));
    2425             :   test_value = Handle<Smi>(Smi::FromInt(2), isolate);
    2426           4 :   result_obj = ft.CallChecked<Smi>(test_value);
    2427          12 :   CHECK_EQ(
    2428             :       result_obj->value(),
    2429             :       static_cast<int>(JSObject::NewElementsCapacity(test_value->value())));
    2430             :   test_value = Handle<Smi>(Smi::FromInt(1025), isolate);
    2431           4 :   result_obj = ft.CallChecked<Smi>(test_value);
    2432          12 :   CHECK_EQ(
    2433             :       result_obj->value(),
    2434             :       static_cast<int>(JSObject::NewElementsCapacity(test_value->value())));
    2435           4 : }
    2436             : 
    2437       26643 : TEST(NewElementsCapacitySmi) {
    2438             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2439           8 :   CodeAssemblerTester asm_tester(isolate, 1);
    2440           4 :   CodeStubAssembler m(asm_tester.state());
    2441           8 :   m.Return(m.CalculateNewElementsCapacity(m.Parameter(0),
    2442           4 :                                           CodeStubAssembler::SMI_PARAMETERS));
    2443             : 
    2444           4 :   FunctionTester ft(asm_tester.GenerateCode(), 1);
    2445             :   Handle<Smi> test_value = Handle<Smi>(Smi::FromInt(0), isolate);
    2446           4 :   Handle<Smi> result_obj = ft.CallChecked<Smi>(test_value);
    2447          12 :   CHECK_EQ(
    2448             :       result_obj->value(),
    2449             :       static_cast<int>(JSObject::NewElementsCapacity(test_value->value())));
    2450             :   test_value = Handle<Smi>(Smi::FromInt(1), isolate);
    2451           4 :   result_obj = ft.CallChecked<Smi>(test_value);
    2452          12 :   CHECK_EQ(
    2453             :       result_obj->value(),
    2454             :       static_cast<int>(JSObject::NewElementsCapacity(test_value->value())));
    2455             :   test_value = Handle<Smi>(Smi::FromInt(2), isolate);
    2456           4 :   result_obj = ft.CallChecked<Smi>(test_value);
    2457          12 :   CHECK_EQ(
    2458             :       result_obj->value(),
    2459             :       static_cast<int>(JSObject::NewElementsCapacity(test_value->value())));
    2460             :   test_value = Handle<Smi>(Smi::FromInt(1025), isolate);
    2461           4 :   result_obj = ft.CallChecked<Smi>(test_value);
    2462          12 :   CHECK_EQ(
    2463             :       result_obj->value(),
    2464             :       static_cast<int>(JSObject::NewElementsCapacity(test_value->value())));
    2465           4 : }
    2466             : 
    2467       26643 : TEST(AllocateFunctionWithMapAndContext) {
    2468             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2469             : 
    2470             :   const int kNumParams = 1;
    2471           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    2472             :   PromiseBuiltinsAssembler m(asm_tester.state());
    2473             : 
    2474           4 :   Node* const context = m.Parameter(kNumParams + 2);
    2475           8 :   Node* const native_context = m.LoadNativeContext(context);
    2476             :   Node* const promise =
    2477           8 :       m.AllocateAndInitJSPromise(context, m.UndefinedConstant());
    2478             :   Node* promise_context = m.CreatePromiseResolvingFunctionsContext(
    2479           8 :       promise, m.BooleanConstant(false), native_context);
    2480           8 :   Node* resolve_info = m.LoadContextElement(
    2481             :       native_context,
    2482           4 :       Context::PROMISE_CAPABILITY_DEFAULT_RESOLVE_SHARED_FUN_INDEX);
    2483           8 :   Node* const map = m.LoadContextElement(
    2484           4 :       native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
    2485             :   Node* const resolve =
    2486           4 :       m.AllocateFunctionWithMapAndContext(map, resolve_info, promise_context);
    2487           4 :   m.Return(resolve);
    2488             : 
    2489           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    2490             :   Handle<Object> result_obj =
    2491           8 :       ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
    2492           4 :   CHECK(result_obj->IsJSFunction());
    2493             :   Handle<JSFunction> fun = Handle<JSFunction>::cast(result_obj);
    2494           8 :   CHECK_EQ(ReadOnlyRoots(isolate).empty_property_array(),
    2495             :            fun->property_array());
    2496           4 :   CHECK_EQ(ReadOnlyRoots(isolate).empty_fixed_array(), fun->elements());
    2497           4 :   CHECK_EQ(isolate->heap()->many_closures_cell(), fun->raw_feedback_cell());
    2498           4 :   CHECK(!fun->has_prototype_slot());
    2499           8 :   CHECK_EQ(*isolate->promise_capability_default_resolve_shared_fun(),
    2500             :            fun->shared());
    2501          12 :   CHECK_EQ(isolate->promise_capability_default_resolve_shared_fun()->GetCode(),
    2502             :            fun->code());
    2503           4 : }
    2504             : 
    2505       26643 : TEST(CreatePromiseGetCapabilitiesExecutorContext) {
    2506             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2507             : 
    2508             :   const int kNumParams = 1;
    2509           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    2510             :   PromiseBuiltinsAssembler m(asm_tester.state());
    2511             : 
    2512           4 :   Node* const context = m.Parameter(kNumParams + 2);
    2513           8 :   Node* const native_context = m.LoadNativeContext(context);
    2514             : 
    2515           8 :   Node* const map = m.LoadRoot(RootIndex::kPromiseCapabilityMap);
    2516           4 :   Node* const capability = m.AllocateStruct(map);
    2517             :   m.StoreObjectFieldNoWriteBarrier(
    2518           8 :       capability, PromiseCapability::kPromiseOffset, m.UndefinedConstant());
    2519             :   m.StoreObjectFieldNoWriteBarrier(
    2520           8 :       capability, PromiseCapability::kResolveOffset, m.UndefinedConstant());
    2521             :   m.StoreObjectFieldNoWriteBarrier(capability, PromiseCapability::kRejectOffset,
    2522           8 :                                    m.UndefinedConstant());
    2523             :   Node* const executor_context =
    2524           4 :       m.CreatePromiseGetCapabilitiesExecutorContext(capability, native_context);
    2525           4 :   m.Return(executor_context);
    2526             : 
    2527           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    2528             :   Handle<Object> result_obj =
    2529           8 :       ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
    2530           4 :   CHECK(result_obj->IsContext());
    2531             :   Handle<Context> context_js = Handle<Context>::cast(result_obj);
    2532           4 :   CHECK_EQ(PromiseBuiltins::kCapabilitiesContextLength, context_js->length());
    2533          12 :   CHECK_EQ(isolate->native_context()->scope_info(), context_js->scope_info());
    2534           8 :   CHECK_EQ(ReadOnlyRoots(isolate).the_hole_value(), context_js->extension());
    2535           8 :   CHECK_EQ(*isolate->native_context(), context_js->native_context());
    2536           4 :   CHECK(
    2537             :       context_js->get(PromiseBuiltins::kCapabilitySlot)->IsPromiseCapability());
    2538           4 : }
    2539             : 
    2540       26643 : TEST(NewPromiseCapability) {
    2541             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2542             : 
    2543             :   {  // Builtin Promise
    2544             :     const int kNumParams = 1;
    2545           8 :     CodeAssemblerTester asm_tester(isolate, kNumParams);
    2546             :     PromiseBuiltinsAssembler m(asm_tester.state());
    2547             : 
    2548           4 :     Node* const context = m.Parameter(kNumParams + 2);
    2549           8 :     Node* const native_context = m.LoadNativeContext(context);
    2550             :     Node* const promise_constructor =
    2551           8 :         m.LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
    2552             : 
    2553           8 :     Node* const debug_event = m.TrueConstant();
    2554             :     Node* const capability =
    2555           8 :         m.CallBuiltin(Builtins::kNewPromiseCapability, context,
    2556           4 :                       promise_constructor, debug_event);
    2557           4 :     m.Return(capability);
    2558             : 
    2559           4 :     FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    2560             : 
    2561             :     Handle<Object> result_obj =
    2562           8 :         ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
    2563           4 :     CHECK(result_obj->IsPromiseCapability());
    2564             :     Handle<PromiseCapability> result =
    2565             :         Handle<PromiseCapability>::cast(result_obj);
    2566             : 
    2567           4 :     CHECK(result->promise()->IsJSPromise());
    2568           4 :     CHECK(result->resolve()->IsJSFunction());
    2569           4 :     CHECK(result->reject()->IsJSFunction());
    2570           8 :     CHECK_EQ(*isolate->promise_capability_default_reject_shared_fun(),
    2571             :              JSFunction::cast(result->reject())->shared());
    2572           8 :     CHECK_EQ(*isolate->promise_capability_default_resolve_shared_fun(),
    2573             :              JSFunction::cast(result->resolve())->shared());
    2574             : 
    2575             :     Handle<JSFunction> callbacks[] = {
    2576             :         handle(JSFunction::cast(result->resolve()), isolate),
    2577           8 :         handle(JSFunction::cast(result->reject()), isolate)};
    2578             : 
    2579          20 :     for (auto&& callback : callbacks) {
    2580             :       Handle<Context> context(Context::cast(callback->context()), isolate);
    2581          24 :       CHECK_EQ(isolate->native_context()->scope_info(), context->scope_info());
    2582          16 :       CHECK_EQ(ReadOnlyRoots(isolate).the_hole_value(), context->extension());
    2583          16 :       CHECK_EQ(*isolate->native_context(), context->native_context());
    2584           8 :       CHECK_EQ(PromiseBuiltins::kPromiseContextLength, context->length());
    2585           8 :       CHECK_EQ(context->get(PromiseBuiltins::kPromiseSlot), result->promise());
    2586             :     }
    2587             :   }
    2588             : 
    2589             :   {  // Custom Promise
    2590             :     const int kNumParams = 2;
    2591           8 :     CodeAssemblerTester asm_tester(isolate, kNumParams);
    2592             :     PromiseBuiltinsAssembler m(asm_tester.state());
    2593             : 
    2594           4 :     Node* const context = m.Parameter(kNumParams + 2);
    2595             : 
    2596           4 :     Node* const constructor = m.Parameter(1);
    2597           8 :     Node* const debug_event = m.TrueConstant();
    2598           8 :     Node* const capability = m.CallBuiltin(Builtins::kNewPromiseCapability,
    2599           4 :                                            context, constructor, debug_event);
    2600           4 :     m.Return(capability);
    2601             : 
    2602           4 :     FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    2603             : 
    2604             :     Handle<JSFunction> constructor_fn =
    2605             :         Handle<JSFunction>::cast(v8::Utils::OpenHandle(*CompileRun(
    2606             :             "(function FakePromise(executor) {"
    2607             :             "  var self = this;"
    2608             :             "  function resolve(value) { self.resolvedValue = value; }"
    2609             :             "  function reject(reason) { self.rejectedReason = reason; }"
    2610             :             "  executor(resolve, reject);"
    2611             :             "})")));
    2612             : 
    2613             :     Handle<Object> result_obj =
    2614           8 :         ft.Call(isolate->factory()->undefined_value(), constructor_fn)
    2615             :             .ToHandleChecked();
    2616           4 :     CHECK(result_obj->IsPromiseCapability());
    2617             :     Handle<PromiseCapability> result =
    2618             :         Handle<PromiseCapability>::cast(result_obj);
    2619             : 
    2620           4 :     CHECK(result->promise()->IsJSObject());
    2621             :     Handle<JSObject> promise(JSObject::cast(result->promise()), isolate);
    2622           4 :     CHECK_EQ(constructor_fn->prototype_or_initial_map(), promise->map());
    2623           4 :     CHECK(result->resolve()->IsJSFunction());
    2624           4 :     CHECK(result->reject()->IsJSFunction());
    2625             : 
    2626             :     Handle<String> resolved_str =
    2627           4 :         isolate->factory()->NewStringFromAsciiChecked("resolvedStr");
    2628             :     Handle<String> rejected_str =
    2629           4 :         isolate->factory()->NewStringFromAsciiChecked("rejectedStr");
    2630             : 
    2631             :     Handle<Object> argv1[] = {resolved_str};
    2632             :     Handle<Object> ret =
    2633           8 :         Execution::Call(isolate, handle(result->resolve(), isolate),
    2634           4 :                         isolate->factory()->undefined_value(), 1, argv1)
    2635             :             .ToHandleChecked();
    2636             : 
    2637             :     Handle<Object> prop1 =
    2638           8 :         JSReceiver::GetProperty(isolate, promise, "resolvedValue")
    2639             :             .ToHandleChecked();
    2640           4 :     CHECK_EQ(*resolved_str, *prop1);
    2641             : 
    2642             :     Handle<Object> argv2[] = {rejected_str};
    2643           8 :     ret = Execution::Call(isolate, handle(result->reject(), isolate),
    2644           4 :                           isolate->factory()->undefined_value(), 1, argv2)
    2645             :               .ToHandleChecked();
    2646             :     Handle<Object> prop2 =
    2647           8 :         JSReceiver::GetProperty(isolate, promise, "rejectedReason")
    2648             :             .ToHandleChecked();
    2649           4 :     CHECK_EQ(*rejected_str, *prop2);
    2650             :   }
    2651           4 : }
    2652             : 
    2653       26643 : TEST(DirectMemoryTest8BitWord32Immediate) {
    2654             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2655             : 
    2656             :   const int kNumParams = 0;
    2657           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    2658           4 :   CodeStubAssembler m(asm_tester.state());
    2659           4 :   int8_t buffer[] = {1, 2, 4, 8, 17, 33, 65, 127};
    2660             :   const int element_count = 8;
    2661           4 :   Label bad(&m);
    2662             : 
    2663           8 :   Node* buffer_node = m.IntPtrConstant(reinterpret_cast<intptr_t>(buffer));
    2664          68 :   for (size_t i = 0; i < element_count; ++i) {
    2665         544 :     for (size_t j = 0; j < element_count; ++j) {
    2666         256 :       Node* loaded = m.LoadBufferObject(buffer_node, static_cast<int>(i),
    2667         256 :                                         MachineType::Uint8());
    2668         768 :       Node* masked = m.Word32And(loaded, m.Int32Constant(buffer[j]));
    2669         256 :       if ((buffer[j] & buffer[i]) != 0) {
    2670         408 :         m.GotoIf(m.Word32Equal(masked, m.Int32Constant(0)), &bad);
    2671             :       } else {
    2672         360 :         m.GotoIf(m.Word32NotEqual(masked, m.Int32Constant(0)), &bad);
    2673             :       }
    2674             :     }
    2675             :   }
    2676             : 
    2677           8 :   m.Return(m.SmiConstant(1));
    2678             : 
    2679           4 :   m.BIND(&bad);
    2680           8 :   m.Return(m.SmiConstant(0));
    2681             : 
    2682           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    2683           8 :   CHECK_EQ(1, ft.CallChecked<Smi>()->value());
    2684           4 : }
    2685             : 
    2686       26643 : TEST(DirectMemoryTest16BitWord32Immediate) {
    2687             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2688             :   const int kNumParams = 0;
    2689           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    2690           4 :   CodeStubAssembler m(asm_tester.state());
    2691           4 :   int16_t buffer[] = {156, 2234, 4544, 8444, 1723, 3888, 658, 1278};
    2692             :   const int element_count = 8;
    2693           4 :   Label bad(&m);
    2694             : 
    2695           8 :   Node* buffer_node = m.IntPtrConstant(reinterpret_cast<intptr_t>(buffer));
    2696          68 :   for (size_t i = 0; i < element_count; ++i) {
    2697         544 :     for (size_t j = 0; j < element_count; ++j) {
    2698             :       Node* loaded =
    2699         256 :           m.LoadBufferObject(buffer_node, static_cast<int>(i * sizeof(int16_t)),
    2700         256 :                              MachineType::Uint16());
    2701         768 :       Node* masked = m.Word32And(loaded, m.Int32Constant(buffer[j]));
    2702         256 :       if ((buffer[j] & buffer[i]) != 0) {
    2703         768 :         m.GotoIf(m.Word32Equal(masked, m.Int32Constant(0)), &bad);
    2704             :       } else {
    2705           0 :         m.GotoIf(m.Word32NotEqual(masked, m.Int32Constant(0)), &bad);
    2706             :       }
    2707             :     }
    2708             :   }
    2709             : 
    2710           8 :   m.Return(m.SmiConstant(1));
    2711             : 
    2712           4 :   m.BIND(&bad);
    2713           8 :   m.Return(m.SmiConstant(0));
    2714             : 
    2715           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    2716           8 :   CHECK_EQ(1, ft.CallChecked<Smi>()->value());
    2717           4 : }
    2718             : 
    2719       26643 : TEST(DirectMemoryTest8BitWord32) {
    2720             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2721             :   const int kNumParams = 0;
    2722           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    2723           4 :   CodeStubAssembler m(asm_tester.state());
    2724           4 :   int8_t buffer[] = {1, 2, 4, 8, 17, 33, 65, 127, 67, 38};
    2725             :   const int element_count = 10;
    2726           4 :   Label bad(&m);
    2727             :   Node* constants[element_count];
    2728             : 
    2729           8 :   Node* buffer_node = m.IntPtrConstant(reinterpret_cast<intptr_t>(buffer));
    2730          84 :   for (size_t i = 0; i < element_count; ++i) {
    2731          40 :     constants[i] = m.LoadBufferObject(buffer_node, static_cast<int>(i),
    2732          40 :                                       MachineType::Uint8());
    2733             :   }
    2734             : 
    2735          84 :   for (size_t i = 0; i < element_count; ++i) {
    2736         840 :     for (size_t j = 0; j < element_count; ++j) {
    2737         400 :       Node* loaded = m.LoadBufferObject(buffer_node, static_cast<int>(i),
    2738         400 :                                         MachineType::Uint8());
    2739        1200 :       Node* masked = m.Word32And(loaded, constants[j]);
    2740         400 :       if ((buffer[j] & buffer[i]) != 0) {
    2741         696 :         m.GotoIf(m.Word32Equal(masked, m.Int32Constant(0)), &bad);
    2742             :       } else {
    2743         504 :         m.GotoIf(m.Word32NotEqual(masked, m.Int32Constant(0)), &bad);
    2744             :       }
    2745             : 
    2746        1600 :       masked = m.Word32And(constants[i], constants[j]);
    2747         400 :       if ((buffer[j] & buffer[i]) != 0) {
    2748         696 :         m.GotoIf(m.Word32Equal(masked, m.Int32Constant(0)), &bad);
    2749             :       } else {
    2750         504 :         m.GotoIf(m.Word32NotEqual(masked, m.Int32Constant(0)), &bad);
    2751             :       }
    2752             :     }
    2753             :   }
    2754             : 
    2755           8 :   m.Return(m.SmiConstant(1));
    2756             : 
    2757           4 :   m.BIND(&bad);
    2758           8 :   m.Return(m.SmiConstant(0));
    2759             : 
    2760           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    2761           8 :   CHECK_EQ(1, ft.CallChecked<Smi>()->value());
    2762           4 : }
    2763             : 
    2764       26643 : TEST(DirectMemoryTest16BitWord32) {
    2765             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2766             :   const int kNumParams = 0;
    2767           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    2768           4 :   CodeStubAssembler m(asm_tester.state());
    2769           4 :   int16_t buffer[] = {1, 2, 4, 8, 12345, 33, 65, 255, 67, 3823};
    2770             :   const int element_count = 10;
    2771           4 :   Label bad(&m);
    2772             :   Node* constants[element_count];
    2773             : 
    2774           8 :   Node* buffer_node1 = m.IntPtrConstant(reinterpret_cast<intptr_t>(buffer));
    2775          84 :   for (size_t i = 0; i < element_count; ++i) {
    2776             :     constants[i] =
    2777          40 :         m.LoadBufferObject(buffer_node1, static_cast<int>(i * sizeof(int16_t)),
    2778          40 :                            MachineType::Uint16());
    2779             :   }
    2780           8 :   Node* buffer_node2 = m.IntPtrConstant(reinterpret_cast<intptr_t>(buffer));
    2781             : 
    2782          84 :   for (size_t i = 0; i < element_count; ++i) {
    2783         840 :     for (size_t j = 0; j < element_count; ++j) {
    2784         400 :       Node* loaded = m.LoadBufferObject(buffer_node1,
    2785             :                                         static_cast<int>(i * sizeof(int16_t)),
    2786         400 :                                         MachineType::Uint16());
    2787        1200 :       Node* masked = m.Word32And(loaded, constants[j]);
    2788         400 :       if ((buffer[j] & buffer[i]) != 0) {
    2789         816 :         m.GotoIf(m.Word32Equal(masked, m.Int32Constant(0)), &bad);
    2790             :       } else {
    2791         384 :         m.GotoIf(m.Word32NotEqual(masked, m.Int32Constant(0)), &bad);
    2792             :       }
    2793             : 
    2794             :       // Force a memory access relative to a high-number register.
    2795             :       loaded = m.LoadBufferObject(buffer_node2,
    2796             :                                   static_cast<int>(i * sizeof(int16_t)),
    2797         400 :                                   MachineType::Uint16());
    2798        1200 :       masked = m.Word32And(loaded, constants[j]);
    2799         400 :       if ((buffer[j] & buffer[i]) != 0) {
    2800         816 :         m.GotoIf(m.Word32Equal(masked, m.Int32Constant(0)), &bad);
    2801             :       } else {
    2802         384 :         m.GotoIf(m.Word32NotEqual(masked, m.Int32Constant(0)), &bad);
    2803             :       }
    2804             : 
    2805        1600 :       masked = m.Word32And(constants[i], constants[j]);
    2806         400 :       if ((buffer[j] & buffer[i]) != 0) {
    2807         816 :         m.GotoIf(m.Word32Equal(masked, m.Int32Constant(0)), &bad);
    2808             :       } else {
    2809         384 :         m.GotoIf(m.Word32NotEqual(masked, m.Int32Constant(0)), &bad);
    2810             :       }
    2811             :     }
    2812             :   }
    2813             : 
    2814           8 :   m.Return(m.SmiConstant(1));
    2815             : 
    2816           4 :   m.BIND(&bad);
    2817           8 :   m.Return(m.SmiConstant(0));
    2818             : 
    2819           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    2820           8 :   CHECK_EQ(1, ft.CallChecked<Smi>()->value());
    2821           4 : }
    2822             : 
    2823       26643 : TEST(LoadJSArrayElementsMap) {
    2824             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2825             :   const int kNumParams = 1;
    2826           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    2827             :   {
    2828           4 :     CodeStubAssembler m(asm_tester.state());
    2829           4 :     Node* context = m.Parameter(kNumParams + 2);
    2830           8 :     Node* native_context = m.LoadNativeContext(context);
    2831          12 :     Node* kind = m.SmiToInt32(m.Parameter(0));
    2832           8 :     m.Return(m.LoadJSArrayElementsMap(kind, native_context));
    2833             :   }
    2834             : 
    2835           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    2836          52 :   for (int kind = 0; kind <= HOLEY_DOUBLE_ELEMENTS; kind++) {
    2837             :     Handle<Map> csa_result =
    2838          24 :         ft.CallChecked<Map>(handle(Smi::FromInt(kind), isolate));
    2839             :     ElementsKind elements_kind = static_cast<ElementsKind>(kind);
    2840             :     Handle<Map> result(
    2841          72 :         isolate->native_context()->GetInitialJSArrayMap(elements_kind),
    2842          24 :         isolate);
    2843          24 :     CHECK_EQ(*csa_result, *result);
    2844             :   }
    2845           4 : }
    2846             : 
    2847       26643 : TEST(AllocateStruct) {
    2848             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2849             : 
    2850             :   const int kNumParams = 3;
    2851           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    2852           4 :   CodeStubAssembler m(asm_tester.state());
    2853             : 
    2854             :   {
    2855           4 :     Node* map = m.Parameter(0);
    2856           4 :     Node* result = m.AllocateStruct(map);
    2857             : 
    2858           4 :     m.Return(result);
    2859             :   }
    2860             : 
    2861           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    2862             : 
    2863             :   Handle<Map> maps[] = {
    2864             :       handle(ReadOnlyRoots(isolate).tuple3_map(), isolate),
    2865             :       handle(ReadOnlyRoots(isolate).tuple2_map(), isolate),
    2866           8 :   };
    2867             : 
    2868             :   {
    2869          20 :     for (size_t i = 0; i < 2; i++) {
    2870           8 :       Handle<Map> map = maps[i];
    2871             :       Handle<Struct> result =
    2872          16 :           Handle<Struct>::cast(ft.Call(map).ToHandleChecked());
    2873           8 :       CHECK_EQ(result->map(), *map);
    2874             : #ifdef VERIFY_HEAP
    2875             :       isolate->heap()->Verify();
    2876             : #endif
    2877             :     }
    2878             :   }
    2879           4 : }
    2880             : 
    2881       26643 : TEST(GotoIfNotWhiteSpaceOrLineTerminator) {
    2882             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2883             : 
    2884             :   const int kNumParams = 1;
    2885           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    2886             :   StringTrimAssembler m(asm_tester.state());
    2887             : 
    2888             :   {  // Returns true if whitespace, false otherwise.
    2889           4 :     Label if_not_whitespace(&m);
    2890             : 
    2891          12 :     m.GotoIfNotWhiteSpaceOrLineTerminator(m.SmiToInt32(m.Parameter(0)),
    2892           4 :                                           &if_not_whitespace);
    2893           8 :     m.Return(m.TrueConstant());
    2894             : 
    2895           4 :     m.BIND(&if_not_whitespace);
    2896           8 :     m.Return(m.FalseConstant());
    2897             :   }
    2898           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    2899             : 
    2900           4 :   Handle<Object> true_value = ft.true_value();
    2901           4 :   Handle<Object> false_value = ft.false_value();
    2902             : 
    2903      524284 :   for (uc16 c = 0; c < 0xFFFF; c++) {
    2904             :     Handle<Object> expected_value =
    2905      524280 :         IsWhiteSpaceOrLineTerminator(c) ? true_value : false_value;
    2906             :     ft.CheckCall(expected_value, handle(Smi::FromInt(c), isolate));
    2907             :   }
    2908           4 : }
    2909             : 
    2910       26643 : TEST(BranchIfNumberRelationalComparison) {
    2911             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2912             :   Factory* f = isolate->factory();
    2913             :   const int kNumParams = 2;
    2914           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    2915             :   {
    2916           4 :     CodeStubAssembler m(asm_tester.state());
    2917           4 :     Label return_true(&m), return_false(&m);
    2918           4 :     m.BranchIfNumberRelationalComparison(Operation::kGreaterThanOrEqual,
    2919             :                                          m.Parameter(0), m.Parameter(1),
    2920           4 :                                          &return_true, &return_false);
    2921           4 :     m.BIND(&return_true);
    2922           8 :     m.Return(m.BooleanConstant(true));
    2923           4 :     m.BIND(&return_false);
    2924           8 :     m.Return(m.BooleanConstant(false));
    2925             :   }
    2926             : 
    2927           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    2928             : 
    2929           4 :   ft.CheckTrue(f->NewNumber(0), f->NewNumber(0));
    2930           4 :   ft.CheckTrue(f->NewNumber(1), f->NewNumber(0));
    2931           4 :   ft.CheckTrue(f->NewNumber(1), f->NewNumber(1));
    2932           4 :   ft.CheckFalse(f->NewNumber(0), f->NewNumber(1));
    2933           4 :   ft.CheckFalse(f->NewNumber(-1), f->NewNumber(0));
    2934           4 :   ft.CheckTrue(f->NewNumber(-1), f->NewNumber(-1));
    2935             : 
    2936           4 :   ft.CheckTrue(f->NewNumber(-1), f->NewNumber(-1.5));
    2937           4 :   ft.CheckFalse(f->NewNumber(-1.5), f->NewNumber(-1));
    2938           4 :   ft.CheckTrue(f->NewNumber(-1.5), f->NewNumber(-1.5));
    2939           4 : }
    2940             : 
    2941       26643 : TEST(IsNumberArrayIndex) {
    2942             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2943             :   const int kNumParams = 1;
    2944           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    2945             :   {
    2946           4 :     CodeStubAssembler m(asm_tester.state());
    2947           4 :     TNode<Number> number = m.CAST(m.Parameter(0));
    2948           4 :     m.Return(
    2949          16 :         m.SmiFromInt32(m.UncheckedCast<Int32T>(m.IsNumberArrayIndex(number))));
    2950             :   }
    2951             : 
    2952           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    2953             : 
    2954             :   double indices[] = {Smi::kMinValue,
    2955             :                       -11,
    2956             :                       -1,
    2957             :                       0,
    2958             :                       1,
    2959             :                       2,
    2960             :                       Smi::kMaxValue,
    2961             :                       -11.0,
    2962             :                       -11.1,
    2963             :                       -2.0,
    2964             :                       -1.0,
    2965             :                       -0.0,
    2966             :                       0.0,
    2967             :                       0.00001,
    2968             :                       0.1,
    2969             :                       1,
    2970             :                       2,
    2971             :                       Smi::kMinValue - 1.0,
    2972             :                       Smi::kMinValue + 1.0,
    2973             :                       Smi::kMinValue + 1.2,
    2974             :                       kMaxInt + 1.2,
    2975             :                       kMaxInt - 10.0,
    2976             :                       kMaxInt - 1.0,
    2977             :                       kMaxInt,
    2978             :                       kMaxInt + 1.0,
    2979           4 :                       kMaxInt + 10.0};
    2980             : 
    2981         212 :   for (size_t i = 0; i < arraysize(indices); i++) {
    2982         104 :     Handle<Object> index = isolate->factory()->NewNumber(indices[i]);
    2983             :     uint32_t array_index;
    2984         416 :     CHECK_EQ(index->ToArrayIndex(&array_index),
    2985             :              (ft.CallChecked<Smi>(index)->value() == 1));
    2986             :   }
    2987           4 : }
    2988             : 
    2989       26643 : TEST(NumberMinMax) {
    2990             :   Isolate* isolate(CcTest::InitIsolateOnce());
    2991             :   const int kNumParams = 2;
    2992           8 :   CodeAssemblerTester asm_tester_min(isolate, kNumParams);
    2993             :   {
    2994           4 :     CodeStubAssembler m(asm_tester_min.state());
    2995          16 :     m.Return(m.NumberMin(m.Parameter(0), m.Parameter(1)));
    2996             :   }
    2997           4 :   FunctionTester ft_min(asm_tester_min.GenerateCode(), kNumParams);
    2998             : 
    2999           8 :   CodeAssemblerTester asm_tester_max(isolate, kNumParams);
    3000             :   {
    3001           4 :     CodeStubAssembler m(asm_tester_max.state());
    3002          16 :     m.Return(m.NumberMax(m.Parameter(0), m.Parameter(1)));
    3003             :   }
    3004           4 :   FunctionTester ft_max(asm_tester_max.GenerateCode(), kNumParams);
    3005             : 
    3006             :   // Test smi values.
    3007             :   Handle<Smi> smi_1(Smi::FromInt(1), isolate);
    3008             :   Handle<Smi> smi_2(Smi::FromInt(2), isolate);
    3009             :   Handle<Smi> smi_5(Smi::FromInt(5), isolate);
    3010           8 :   CHECK_EQ(ft_min.CallChecked<Smi>(smi_1, smi_2)->value(), 1);
    3011           8 :   CHECK_EQ(ft_min.CallChecked<Smi>(smi_2, smi_1)->value(), 1);
    3012           8 :   CHECK_EQ(ft_max.CallChecked<Smi>(smi_1, smi_2)->value(), 2);
    3013           8 :   CHECK_EQ(ft_max.CallChecked<Smi>(smi_2, smi_1)->value(), 2);
    3014             : 
    3015             :   // Test double values.
    3016           4 :   Handle<Object> double_a = isolate->factory()->NewNumber(2.5);
    3017           4 :   Handle<Object> double_b = isolate->factory()->NewNumber(3.5);
    3018             :   Handle<Object> nan =
    3019           4 :       isolate->factory()->NewNumber(std::numeric_limits<double>::quiet_NaN());
    3020           4 :   Handle<Object> infinity = isolate->factory()->NewNumber(V8_INFINITY);
    3021             : 
    3022           8 :   CHECK_EQ(ft_min.CallChecked<HeapNumber>(double_a, double_b)->value(), 2.5);
    3023           8 :   CHECK_EQ(ft_min.CallChecked<HeapNumber>(double_b, double_a)->value(), 2.5);
    3024           8 :   CHECK_EQ(ft_min.CallChecked<HeapNumber>(infinity, double_a)->value(), 2.5);
    3025           8 :   CHECK_EQ(ft_min.CallChecked<HeapNumber>(double_a, infinity)->value(), 2.5);
    3026           8 :   CHECK(std::isnan(ft_min.CallChecked<HeapNumber>(nan, double_a)->value()));
    3027           8 :   CHECK(std::isnan(ft_min.CallChecked<HeapNumber>(double_a, nan)->value()));
    3028             : 
    3029           8 :   CHECK_EQ(ft_max.CallChecked<HeapNumber>(double_a, double_b)->value(), 3.5);
    3030           8 :   CHECK_EQ(ft_max.CallChecked<HeapNumber>(double_b, double_a)->value(), 3.5);
    3031           8 :   CHECK_EQ(ft_max.CallChecked<HeapNumber>(infinity, double_a)->value(),
    3032             :            V8_INFINITY);
    3033           8 :   CHECK_EQ(ft_max.CallChecked<HeapNumber>(double_a, infinity)->value(),
    3034             :            V8_INFINITY);
    3035           8 :   CHECK(std::isnan(ft_max.CallChecked<HeapNumber>(nan, double_a)->value()));
    3036           8 :   CHECK(std::isnan(ft_max.CallChecked<HeapNumber>(double_a, nan)->value()));
    3037             : 
    3038             :   // Mixed smi/double values.
    3039           8 :   CHECK_EQ(ft_max.CallChecked<HeapNumber>(smi_1, double_b)->value(), 3.5);
    3040           8 :   CHECK_EQ(ft_max.CallChecked<HeapNumber>(double_b, smi_1)->value(), 3.5);
    3041           8 :   CHECK_EQ(ft_min.CallChecked<HeapNumber>(smi_5, double_b)->value(), 3.5);
    3042           8 :   CHECK_EQ(ft_min.CallChecked<HeapNumber>(double_b, smi_5)->value(), 3.5);
    3043           4 : }
    3044             : 
    3045       26643 : TEST(NumberAddSub) {
    3046             :   Isolate* isolate(CcTest::InitIsolateOnce());
    3047             :   const int kNumParams = 2;
    3048           8 :   CodeAssemblerTester asm_tester_add(isolate, kNumParams);
    3049             :   {
    3050           4 :     CodeStubAssembler m(asm_tester_add.state());
    3051          16 :     m.Return(m.NumberAdd(m.Parameter(0), m.Parameter(1)));
    3052             :   }
    3053           4 :   FunctionTester ft_add(asm_tester_add.GenerateCode(), kNumParams);
    3054             : 
    3055           8 :   CodeAssemblerTester asm_tester_sub(isolate, kNumParams);
    3056             :   {
    3057           4 :     CodeStubAssembler m(asm_tester_sub.state());
    3058          16 :     m.Return(m.NumberSub(m.Parameter(0), m.Parameter(1)));
    3059             :   }
    3060           4 :   FunctionTester ft_sub(asm_tester_sub.GenerateCode(), kNumParams);
    3061             : 
    3062             :   // Test smi values.
    3063             :   Handle<Smi> smi_1(Smi::FromInt(1), isolate);
    3064             :   Handle<Smi> smi_2(Smi::FromInt(2), isolate);
    3065           8 :   CHECK_EQ(ft_add.CallChecked<Smi>(smi_1, smi_2)->value(), 3);
    3066           8 :   CHECK_EQ(ft_sub.CallChecked<Smi>(smi_2, smi_1)->value(), 1);
    3067             : 
    3068             :   // Test double values.
    3069           4 :   Handle<Object> double_a = isolate->factory()->NewNumber(2.5);
    3070           4 :   Handle<Object> double_b = isolate->factory()->NewNumber(3.0);
    3071           8 :   CHECK_EQ(ft_add.CallChecked<HeapNumber>(double_a, double_b)->value(), 5.5);
    3072           8 :   CHECK_EQ(ft_sub.CallChecked<HeapNumber>(double_a, double_b)->value(), -.5);
    3073             : 
    3074             :   // Test overflow.
    3075             :   Handle<Smi> smi_max(Smi::FromInt(Smi::kMaxValue), isolate);
    3076             :   Handle<Smi> smi_min(Smi::FromInt(Smi::kMinValue), isolate);
    3077           8 :   CHECK_EQ(ft_add.CallChecked<HeapNumber>(smi_max, smi_1)->value(),
    3078             :            static_cast<double>(Smi::kMaxValue) + 1);
    3079           8 :   CHECK_EQ(ft_sub.CallChecked<HeapNumber>(smi_min, smi_1)->value(),
    3080             :            static_cast<double>(Smi::kMinValue) - 1);
    3081             : 
    3082             :   // Test mixed smi/double values.
    3083           8 :   CHECK_EQ(ft_add.CallChecked<HeapNumber>(smi_1, double_a)->value(), 3.5);
    3084           8 :   CHECK_EQ(ft_add.CallChecked<HeapNumber>(double_a, smi_1)->value(), 3.5);
    3085           8 :   CHECK_EQ(ft_sub.CallChecked<HeapNumber>(smi_1, double_a)->value(), -1.5);
    3086           8 :   CHECK_EQ(ft_sub.CallChecked<HeapNumber>(double_a, smi_1)->value(), 1.5);
    3087           4 : }
    3088             : 
    3089       26643 : TEST(CloneEmptyFixedArray) {
    3090             :   Isolate* isolate(CcTest::InitIsolateOnce());
    3091             :   const int kNumParams = 1;
    3092           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    3093             :   {
    3094           4 :     CodeStubAssembler m(asm_tester.state());
    3095           8 :     m.Return(m.CloneFixedArray(m.Parameter(0)));
    3096             :   }
    3097           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    3098             : 
    3099           4 :   Handle<FixedArray> source(isolate->factory()->empty_fixed_array());
    3100           8 :   Handle<Object> result_raw = ft.Call(source).ToHandleChecked();
    3101             :   FixedArray result(FixedArray::cast(*result_raw));
    3102           4 :   CHECK_EQ(0, result->length());
    3103           4 :   CHECK_EQ(*(isolate->factory()->empty_fixed_array()), result);
    3104           4 : }
    3105             : 
    3106       26643 : TEST(CloneFixedArray) {
    3107             :   Isolate* isolate(CcTest::InitIsolateOnce());
    3108             :   const int kNumParams = 1;
    3109           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    3110             :   {
    3111           4 :     CodeStubAssembler m(asm_tester.state());
    3112           8 :     m.Return(m.CloneFixedArray(m.Parameter(0)));
    3113             :   }
    3114           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    3115             : 
    3116           4 :   Handle<FixedArray> source(isolate->factory()->NewFixedArrayWithHoles(5));
    3117             :   source->set(1, Smi::FromInt(1234));
    3118           8 :   Handle<Object> result_raw = ft.Call(source).ToHandleChecked();
    3119             :   FixedArray result(FixedArray::cast(*result_raw));
    3120           4 :   CHECK_EQ(5, result->length());
    3121           4 :   CHECK(result->get(0)->IsTheHole(isolate));
    3122           4 :   CHECK_EQ(Smi::cast(result->get(1))->value(), 1234);
    3123           4 :   CHECK(result->get(2)->IsTheHole(isolate));
    3124           4 :   CHECK(result->get(3)->IsTheHole(isolate));
    3125           4 :   CHECK(result->get(4)->IsTheHole(isolate));
    3126           4 : }
    3127             : 
    3128       26643 : TEST(CloneFixedArrayCOW) {
    3129             :   Isolate* isolate(CcTest::InitIsolateOnce());
    3130             :   const int kNumParams = 1;
    3131           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    3132             :   {
    3133           4 :     CodeStubAssembler m(asm_tester.state());
    3134           8 :     m.Return(m.CloneFixedArray(m.Parameter(0)));
    3135             :   }
    3136           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    3137             : 
    3138           4 :   Handle<FixedArray> source(isolate->factory()->NewFixedArrayWithHoles(5));
    3139             :   source->set(1, Smi::FromInt(1234));
    3140           4 :   source->set_map(ReadOnlyRoots(isolate).fixed_cow_array_map());
    3141           8 :   Handle<Object> result_raw = ft.Call(source).ToHandleChecked();
    3142             :   FixedArray result(FixedArray::cast(*result_raw));
    3143           4 :   CHECK_EQ(*source, result);
    3144           4 : }
    3145             : 
    3146       26643 : TEST(ExtractFixedArrayCOWForceCopy) {
    3147             :   Isolate* isolate(CcTest::InitIsolateOnce());
    3148             :   const int kNumParams = 1;
    3149           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    3150             :   {
    3151           4 :     CodeStubAssembler m(asm_tester.state());
    3152             :     CodeStubAssembler::ExtractFixedArrayFlags flags;
    3153             :     flags |= CodeStubAssembler::ExtractFixedArrayFlag::kAllFixedArrays;
    3154          12 :     m.Return(m.ExtractFixedArray(m.Parameter(0), m.SmiConstant(0), nullptr,
    3155             :                                  nullptr, flags,
    3156           8 :                                  CodeStubAssembler::SMI_PARAMETERS));
    3157             :   }
    3158           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    3159             : 
    3160           4 :   Handle<FixedArray> source(isolate->factory()->NewFixedArrayWithHoles(5));
    3161             :   source->set(1, Smi::FromInt(1234));
    3162           4 :   source->set_map(ReadOnlyRoots(isolate).fixed_cow_array_map());
    3163           8 :   Handle<Object> result_raw = ft.Call(source).ToHandleChecked();
    3164             :   FixedArray result(FixedArray::cast(*result_raw));
    3165           4 :   CHECK_NE(*source, result);
    3166           4 :   CHECK_EQ(5, result->length());
    3167           4 :   CHECK(result->get(0)->IsTheHole(isolate));
    3168           4 :   CHECK_EQ(Smi::cast(result->get(1))->value(), 1234);
    3169           4 :   CHECK(result->get(2)->IsTheHole(isolate));
    3170           4 :   CHECK(result->get(3)->IsTheHole(isolate));
    3171           4 :   CHECK(result->get(4)->IsTheHole(isolate));
    3172           4 : }
    3173             : 
    3174       26643 : TEST(ExtractFixedArraySimple) {
    3175             :   Isolate* isolate(CcTest::InitIsolateOnce());
    3176             :   const int kNumParams = 3;
    3177           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    3178             :   {
    3179           4 :     CodeStubAssembler m(asm_tester.state());
    3180             :     CodeStubAssembler::ExtractFixedArrayFlags flags;
    3181             :     flags |= CodeStubAssembler::ExtractFixedArrayFlag::kAllFixedArrays;
    3182             :     flags |= CodeStubAssembler::ExtractFixedArrayFlag::kDontCopyCOW;
    3183           8 :     m.Return(m.ExtractFixedArray(m.Parameter(0), m.Parameter(1), m.Parameter(2),
    3184             :                                  nullptr, flags,
    3185           8 :                                  CodeStubAssembler::SMI_PARAMETERS));
    3186             :   }
    3187           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    3188             : 
    3189           4 :   Handle<FixedArray> source(isolate->factory()->NewFixedArrayWithHoles(5));
    3190             :   source->set(1, Smi::FromInt(1234));
    3191             :   Handle<Object> result_raw =
    3192           8 :       ft.Call(source, Handle<Smi>(Smi::FromInt(1), isolate),
    3193           4 :               Handle<Smi>(Smi::FromInt(2), isolate))
    3194             :           .ToHandleChecked();
    3195             :   FixedArray result(FixedArray::cast(*result_raw));
    3196           4 :   CHECK_EQ(2, result->length());
    3197           4 :   CHECK_EQ(Smi::cast(result->get(0))->value(), 1234);
    3198           4 :   CHECK(result->get(1)->IsTheHole(isolate));
    3199           4 : }
    3200             : 
    3201       26643 : TEST(ExtractFixedArraySimpleSmiConstant) {
    3202             :   Isolate* isolate(CcTest::InitIsolateOnce());
    3203             :   const int kNumParams = 1;
    3204           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    3205             :   {
    3206           4 :     CodeStubAssembler m(asm_tester.state());
    3207             :     CodeStubAssembler::ExtractFixedArrayFlags flags;
    3208             :     flags |= CodeStubAssembler::ExtractFixedArrayFlag::kAllFixedArrays;
    3209             :     flags |= CodeStubAssembler::ExtractFixedArrayFlag::kDontCopyCOW;
    3210          12 :     m.Return(m.ExtractFixedArray(m.Parameter(0), m.SmiConstant(1),
    3211           8 :                                  m.SmiConstant(2), nullptr, flags,
    3212           8 :                                  CodeStubAssembler::SMI_PARAMETERS));
    3213             :   }
    3214           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    3215             : 
    3216           4 :   Handle<FixedArray> source(isolate->factory()->NewFixedArrayWithHoles(5));
    3217             :   source->set(1, Smi::FromInt(1234));
    3218           8 :   Handle<Object> result_raw = ft.Call(source).ToHandleChecked();
    3219             :   FixedArray result(FixedArray::cast(*result_raw));
    3220           4 :   CHECK_EQ(2, result->length());
    3221           4 :   CHECK_EQ(Smi::cast(result->get(0))->value(), 1234);
    3222           4 :   CHECK(result->get(1)->IsTheHole(isolate));
    3223           4 : }
    3224             : 
    3225       26643 : TEST(ExtractFixedArraySimpleIntPtrConstant) {
    3226             :   Isolate* isolate(CcTest::InitIsolateOnce());
    3227             :   const int kNumParams = 1;
    3228           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    3229             :   {
    3230           4 :     CodeStubAssembler m(asm_tester.state());
    3231             :     CodeStubAssembler::ExtractFixedArrayFlags flags;
    3232             :     flags |= CodeStubAssembler::ExtractFixedArrayFlag::kAllFixedArrays;
    3233             :     flags |= CodeStubAssembler::ExtractFixedArrayFlag::kDontCopyCOW;
    3234          12 :     m.Return(m.ExtractFixedArray(m.Parameter(0), m.IntPtrConstant(1),
    3235           8 :                                  m.IntPtrConstant(2), nullptr, flags,
    3236           8 :                                  CodeStubAssembler::INTPTR_PARAMETERS));
    3237             :   }
    3238           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    3239             : 
    3240           4 :   Handle<FixedArray> source(isolate->factory()->NewFixedArrayWithHoles(5));
    3241             :   source->set(1, Smi::FromInt(1234));
    3242           8 :   Handle<Object> result_raw = ft.Call(source).ToHandleChecked();
    3243             :   FixedArray result(FixedArray::cast(*result_raw));
    3244           4 :   CHECK_EQ(2, result->length());
    3245           4 :   CHECK_EQ(Smi::cast(result->get(0))->value(), 1234);
    3246           4 :   CHECK(result->get(1)->IsTheHole(isolate));
    3247           4 : }
    3248             : 
    3249       26643 : TEST(ExtractFixedArraySimpleIntPtrConstantNoDoubles) {
    3250             :   Isolate* isolate(CcTest::InitIsolateOnce());
    3251             :   const int kNumParams = 1;
    3252           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    3253             :   {
    3254           4 :     CodeStubAssembler m(asm_tester.state());
    3255           8 :     m.Return(m.ExtractFixedArray(
    3256          12 :         m.Parameter(0), m.IntPtrConstant(1), m.IntPtrConstant(2), nullptr,
    3257             :         CodeStubAssembler::ExtractFixedArrayFlag::kFixedArrays,
    3258          12 :         CodeStubAssembler::INTPTR_PARAMETERS));
    3259             :   }
    3260           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    3261             : 
    3262           4 :   Handle<FixedArray> source(isolate->factory()->NewFixedArrayWithHoles(5));
    3263             :   source->set(1, Smi::FromInt(1234));
    3264           8 :   Handle<Object> result_raw = ft.Call(source).ToHandleChecked();
    3265             :   FixedArray result(FixedArray::cast(*result_raw));
    3266           4 :   CHECK_EQ(2, result->length());
    3267           4 :   CHECK_EQ(Smi::cast(result->get(0))->value(), 1234);
    3268           4 :   CHECK(result->get(1)->IsTheHole(isolate));
    3269           4 : }
    3270             : 
    3271       26643 : TEST(ExtractFixedArraySimpleIntPtrParameters) {
    3272             :   Isolate* isolate(CcTest::InitIsolateOnce());
    3273             :   const int kNumParams = 3;
    3274           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    3275             :   {
    3276           4 :     CodeStubAssembler m(asm_tester.state());
    3277          12 :     Node* p1_untagged = m.SmiUntag(m.Parameter(1));
    3278          12 :     Node* p2_untagged = m.SmiUntag(m.Parameter(2));
    3279           8 :     m.Return(m.ExtractFixedArray(m.Parameter(0), p1_untagged, p2_untagged));
    3280             :   }
    3281           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    3282             : 
    3283           4 :   Handle<FixedArray> source(isolate->factory()->NewFixedArrayWithHoles(5));
    3284             :   source->set(1, Smi::FromInt(1234));
    3285             :   Handle<Object> result_raw =
    3286           8 :       ft.Call(source, Handle<Smi>(Smi::FromInt(1), isolate),
    3287           4 :               Handle<Smi>(Smi::FromInt(2), isolate))
    3288             :           .ToHandleChecked();
    3289             :   FixedArray result(FixedArray::cast(*result_raw));
    3290           4 :   CHECK_EQ(2, result->length());
    3291           4 :   CHECK_EQ(Smi::cast(result->get(0))->value(), 1234);
    3292           4 :   CHECK(result->get(1)->IsTheHole(isolate));
    3293             : 
    3294             :   Handle<FixedDoubleArray> source_double = Handle<FixedDoubleArray>::cast(
    3295           4 :       isolate->factory()->NewFixedDoubleArray(5));
    3296           4 :   source_double->set(0, 10);
    3297           4 :   source_double->set(1, 11);
    3298           4 :   source_double->set(2, 12);
    3299           4 :   source_double->set(3, 13);
    3300           4 :   source_double->set(4, 14);
    3301             :   Handle<Object> double_result_raw =
    3302           8 :       ft.Call(source_double, Handle<Smi>(Smi::FromInt(1), isolate),
    3303           4 :               Handle<Smi>(Smi::FromInt(2), isolate))
    3304             :           .ToHandleChecked();
    3305             :   FixedDoubleArray double_result = FixedDoubleArray::cast(*double_result_raw);
    3306           4 :   CHECK_EQ(2, double_result->length());
    3307           4 :   CHECK_EQ(double_result->get_scalar(0), 11);
    3308           4 :   CHECK_EQ(double_result->get_scalar(1), 12);
    3309           4 : }
    3310             : 
    3311       26643 : TEST(SingleInputPhiElimination) {
    3312             :   Isolate* isolate(CcTest::InitIsolateOnce());
    3313             :   const int kNumParams = 2;
    3314           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    3315             :   {
    3316           4 :     CodeStubAssembler m(asm_tester.state());
    3317           8 :     Variable temp1(&m, MachineRepresentation::kTagged);
    3318           8 :     Variable temp2(&m, MachineRepresentation::kTagged);
    3319          12 :     Label temp_label(&m, {&temp1, &temp2});
    3320          12 :     Label end_label(&m, {&temp1, &temp2});
    3321           4 :     temp1.Bind(m.Parameter(1));
    3322           4 :     temp2.Bind(m.Parameter(1));
    3323          16 :     m.Branch(m.WordEqual(m.Parameter(0), m.Parameter(1)), &end_label,
    3324           4 :              &temp_label);
    3325           4 :     temp1.Bind(m.Parameter(2));
    3326           4 :     temp2.Bind(m.Parameter(2));
    3327           4 :     m.BIND(&temp_label);
    3328           4 :     m.Goto(&end_label);
    3329           4 :     m.BIND(&end_label);
    3330           8 :     m.Return(temp1.value());
    3331             :   }
    3332           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    3333             :   // Generating code without an assert is enough to make sure that the
    3334             :   // single-input phi is properly eliminated.
    3335           4 : }
    3336             : 
    3337       26643 : TEST(SmallOrderedHashMapAllocate) {
    3338             :   Isolate* isolate(CcTest::InitIsolateOnce());
    3339             :   const int kNumParams = 1;
    3340           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    3341             :   {
    3342           4 :     CodeStubAssembler m(asm_tester.state());
    3343           4 :     TNode<Smi> capacity = m.CAST(m.Parameter(0));
    3344           8 :     m.Return(m.AllocateSmallOrderedHashTable<SmallOrderedHashMap>(
    3345           4 :         m.SmiToIntPtr(capacity)));
    3346             :   }
    3347           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    3348             : 
    3349             :   Factory* factory = isolate->factory();
    3350             :   int capacity = SmallOrderedHashMap::kMinCapacity;
    3351          52 :   while (capacity <= SmallOrderedHashMap::kMaxCapacity) {
    3352             :     Handle<SmallOrderedHashMap> expected =
    3353          24 :         factory->NewSmallOrderedHashMap(capacity);
    3354             :     Handle<Object> result_raw =
    3355          48 :         ft.Call(Handle<Smi>(Smi::FromInt(capacity), isolate)).ToHandleChecked();
    3356             :     Handle<SmallOrderedHashMap> actual = Handle<SmallOrderedHashMap>(
    3357             :         SmallOrderedHashMap::cast(*result_raw), isolate);
    3358          24 :     CHECK_EQ(capacity, actual->Capacity());
    3359          24 :     CHECK_EQ(0, actual->NumberOfElements());
    3360          24 :     CHECK_EQ(0, actual->NumberOfDeletedElements());
    3361          24 :     CHECK_EQ(capacity / SmallOrderedHashMap::kLoadFactor,
    3362             :              actual->NumberOfBuckets());
    3363          72 :     CHECK_EQ(0, memcmp(reinterpret_cast<void*>(expected->address()),
    3364             :                        reinterpret_cast<void*>(actual->address()),
    3365             :                        SmallOrderedHashMap::SizeFor(capacity)));
    3366             : #ifdef VERIFY_HEAP
    3367             :     actual->SmallOrderedHashMapVerify(isolate);
    3368             : #endif
    3369          24 :     capacity = capacity << 1;
    3370             :   }
    3371             : #ifdef VERIFY_HEAP
    3372             :   isolate->heap()->Verify();
    3373             : #endif
    3374           4 : }
    3375             : 
    3376       26643 : TEST(SmallOrderedHashSetAllocate) {
    3377             :   Isolate* isolate(CcTest::InitIsolateOnce());
    3378             :   const int kNumParams = 1;
    3379           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    3380             :   {
    3381           4 :     CodeStubAssembler m(asm_tester.state());
    3382           4 :     TNode<Smi> capacity = m.CAST(m.Parameter(0));
    3383           8 :     m.Return(m.AllocateSmallOrderedHashTable<SmallOrderedHashSet>(
    3384           4 :         m.SmiToIntPtr(capacity)));
    3385             :   }
    3386           4 :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    3387             : 
    3388             :   int capacity = SmallOrderedHashSet::kMinCapacity;
    3389             :   Factory* factory = isolate->factory();
    3390          52 :   while (capacity <= SmallOrderedHashSet::kMaxCapacity) {
    3391             :     Handle<SmallOrderedHashSet> expected =
    3392          24 :         factory->NewSmallOrderedHashSet(capacity);
    3393             :     Handle<Object> result_raw =
    3394          48 :         ft.Call(Handle<Smi>(Smi::FromInt(capacity), isolate)).ToHandleChecked();
    3395             :     Handle<SmallOrderedHashSet> actual = Handle<SmallOrderedHashSet>(
    3396             :         SmallOrderedHashSet::cast(*result_raw), isolate);
    3397          24 :     CHECK_EQ(capacity, actual->Capacity());
    3398          24 :     CHECK_EQ(0, actual->NumberOfElements());
    3399          24 :     CHECK_EQ(0, actual->NumberOfDeletedElements());
    3400          24 :     CHECK_EQ(capacity / SmallOrderedHashSet::kLoadFactor,
    3401             :              actual->NumberOfBuckets());
    3402          72 :     CHECK_EQ(0, memcmp(reinterpret_cast<void*>(expected->address()),
    3403             :                        reinterpret_cast<void*>(actual->address()),
    3404             :                        SmallOrderedHashSet::SizeFor(capacity)));
    3405             : #ifdef VERIFY_HEAP
    3406             :     actual->SmallOrderedHashSetVerify(isolate);
    3407             : #endif
    3408          24 :     capacity = capacity << 1;
    3409             :   }
    3410             : #ifdef VERIFY_HEAP
    3411             :   isolate->heap()->Verify();
    3412             : #endif
    3413           4 : }
    3414             : 
    3415       26643 : TEST(IsDoubleElementsKind) {
    3416             :   Isolate* isolate(CcTest::InitIsolateOnce());
    3417             :   const int kNumParams = 2;
    3418           8 :   CodeAssemblerTester ft_tester(isolate, kNumParams);
    3419             :   {
    3420           4 :     CodeStubAssembler m(ft_tester.state());
    3421           8 :     m.Return(m.SmiFromInt32(m.UncheckedCast<Int32T>(
    3422          16 :         m.IsDoubleElementsKind(m.SmiToInt32(m.Parameter(0))))));
    3423             :   }
    3424           4 :   FunctionTester ft(ft_tester.GenerateCode(), kNumParams);
    3425           8 :   CHECK_EQ(
    3426             :       (*Handle<Smi>::cast(
    3427             :            ft.Call(Handle<Smi>(Smi::FromInt(PACKED_DOUBLE_ELEMENTS), isolate))
    3428             :                .ToHandleChecked()))
    3429             :           ->value(),
    3430             :       1);
    3431           8 :   CHECK_EQ(
    3432             :       (*Handle<Smi>::cast(
    3433             :            ft.Call(Handle<Smi>(Smi::FromInt(HOLEY_DOUBLE_ELEMENTS), isolate))
    3434             :                .ToHandleChecked()))
    3435             :           ->value(),
    3436             :       1);
    3437           8 :   CHECK_EQ((*Handle<Smi>::cast(
    3438             :                 ft.Call(Handle<Smi>(Smi::FromInt(HOLEY_ELEMENTS), isolate))
    3439             :                     .ToHandleChecked()))
    3440             :                ->value(),
    3441             :            0);
    3442           8 :   CHECK_EQ((*Handle<Smi>::cast(
    3443             :                 ft.Call(Handle<Smi>(Smi::FromInt(PACKED_ELEMENTS), isolate))
    3444             :                     .ToHandleChecked()))
    3445             :                ->value(),
    3446             :            0);
    3447           8 :   CHECK_EQ((*Handle<Smi>::cast(
    3448             :                 ft.Call(Handle<Smi>(Smi::FromInt(PACKED_SMI_ELEMENTS), isolate))
    3449             :                     .ToHandleChecked()))
    3450             :                ->value(),
    3451             :            0);
    3452           8 :   CHECK_EQ((*Handle<Smi>::cast(
    3453             :                 ft.Call(Handle<Smi>(Smi::FromInt(HOLEY_SMI_ELEMENTS), isolate))
    3454             :                     .ToHandleChecked()))
    3455             :                ->value(),
    3456             :            0);
    3457           8 :   CHECK_EQ((*Handle<Smi>::cast(
    3458             :                 ft.Call(Handle<Smi>(Smi::FromInt(DICTIONARY_ELEMENTS), isolate))
    3459             :                     .ToHandleChecked()))
    3460             :                ->value(),
    3461             :            0);
    3462           4 : }
    3463             : 
    3464       26643 : TEST(TestCallBuiltinInlineTrampoline) {
    3465             :   if (!i::FLAG_embedded_builtins) return;
    3466             :   Isolate* isolate(CcTest::InitIsolateOnce());
    3467             :   const int kNumParams = 1;
    3468           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    3469           4 :   CodeStubAssembler m(asm_tester.state());
    3470             : 
    3471             :   const int kContextOffset = 2;
    3472           4 :   Node* str = m.Parameter(0);
    3473           4 :   Node* context = m.Parameter(kNumParams + kContextOffset);
    3474             : 
    3475           8 :   Node* index = m.SmiConstant(2);
    3476             : 
    3477          12 :   m.Return(m.CallStub(Builtins::CallableFor(isolate, Builtins::kStringRepeat),
    3478           8 :                       context, str, index));
    3479           4 :   AssemblerOptions options = AssemblerOptions::Default(isolate);
    3480           4 :   options.inline_offheap_trampolines = true;
    3481           4 :   options.use_pc_relative_calls_and_jumps = false;
    3482           4 :   options.isolate_independent_code = false;
    3483           4 :   FunctionTester ft(asm_tester.GenerateCode(options), kNumParams);
    3484           4 :   MaybeHandle<Object> result = ft.Call(MakeString("abcdef"));
    3485           4 :   CHECK(String::Equals(isolate, MakeString("abcdefabcdef"),
    3486             :                        Handle<String>::cast(result.ToHandleChecked())));
    3487             : }
    3488             : 
    3489       26643 : TEST(TestCallBuiltinIndirectLoad) {
    3490             :   if (!i::FLAG_embedded_builtins) return;
    3491             :   Isolate* isolate(CcTest::InitIsolateOnce());
    3492             :   const int kNumParams = 1;
    3493           8 :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    3494           4 :   CodeStubAssembler m(asm_tester.state());
    3495             : 
    3496             :   const int kContextOffset = 2;
    3497           4 :   Node* str = m.Parameter(0);
    3498           4 :   Node* context = m.Parameter(kNumParams + kContextOffset);
    3499             : 
    3500           8 :   Node* index = m.SmiConstant(2);
    3501             : 
    3502          12 :   m.Return(m.CallStub(Builtins::CallableFor(isolate, Builtins::kStringRepeat),
    3503           8 :                       context, str, index));
    3504           4 :   AssemblerOptions options = AssemblerOptions::Default(isolate);
    3505           4 :   options.inline_offheap_trampolines = false;
    3506           4 :   options.use_pc_relative_calls_and_jumps = false;
    3507           4 :   options.isolate_independent_code = true;
    3508           4 :   FunctionTester ft(asm_tester.GenerateCode(options), kNumParams);
    3509           4 :   MaybeHandle<Object> result = ft.Call(MakeString("abcdef"));
    3510           4 :   CHECK(String::Equals(isolate, MakeString("abcdefabcdef"),
    3511             :                        Handle<String>::cast(result.ToHandleChecked())));
    3512             : }
    3513             : 
    3514       26643 : TEST(TestGotoIfDebugExecutionModeChecksSideEffects) {
    3515             :   Isolate* isolate(CcTest::InitIsolateOnce());
    3516           8 :   CodeAssemblerTester asm_tester(isolate, 0);
    3517             :   {
    3518           4 :     CodeStubAssembler m(asm_tester.state());
    3519           4 :     Label is_true(&m), is_false(&m);
    3520           4 :     m.GotoIfDebugExecutionModeChecksSideEffects(&is_true);
    3521           4 :     m.Goto(&is_false);
    3522           4 :     m.BIND(&is_false);
    3523           8 :     m.Return(m.BooleanConstant(false));
    3524             : 
    3525           4 :     m.BIND(&is_true);
    3526           8 :     m.Return(m.BooleanConstant(true));
    3527             :   }
    3528             : 
    3529           4 :   FunctionTester ft(asm_tester.GenerateCode(), 0);
    3530             : 
    3531           4 :   CHECK(isolate->debug_execution_mode() != DebugInfo::kSideEffects);
    3532             : 
    3533           8 :   Handle<Object> result = ft.Call().ToHandleChecked();
    3534           4 :   CHECK(result->IsBoolean());
    3535           4 :   CHECK_EQ(false, result->BooleanValue(isolate));
    3536             : 
    3537           4 :   isolate->debug()->StartSideEffectCheckMode();
    3538           4 :   CHECK(isolate->debug_execution_mode() == DebugInfo::kSideEffects);
    3539             : 
    3540           8 :   result = ft.Call().ToHandleChecked();
    3541           4 :   CHECK(result->IsBoolean());
    3542           4 :   CHECK_EQ(true, result->BooleanValue(isolate));
    3543           4 : }
    3544             : 
    3545             : #ifdef V8_COMPRESS_POINTERS
    3546             : 
    3547             : TEST(CompressedSlotInterleavedGC) {
    3548             :   Isolate* isolate(CcTest::InitIsolateOnce());
    3549             : 
    3550             :   const int kNumParams = 1;
    3551             : 
    3552             :   CodeAssemblerTester asm_tester(isolate, kNumParams);
    3553             :   CodeStubAssembler m(asm_tester.state());
    3554             : 
    3555             :   Node* compressed = m.ChangeTaggedToCompressed(m.Parameter(0));
    3556             : 
    3557             :   m.Print(m.ChangeCompressedToTagged(compressed));
    3558             : 
    3559             :   Node* const context = m.Parameter(kNumParams + 2);
    3560             :   m.CallRuntime(Runtime::kCollectGarbage, context, m.SmiConstant(0));
    3561             : 
    3562             :   m.Return(m.ChangeCompressedToTagged(compressed));
    3563             : 
    3564             :   FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
    3565             :   Handle<Object> result =
    3566             :       ft.Call(isolate->factory()->NewNumber(0.5)).ToHandleChecked();
    3567             :   CHECK(result->IsHeapNumber());
    3568             :   CHECK_EQ(0.5, Handle<HeapNumber>::cast(result)->Number());
    3569             : }
    3570             : 
    3571             : #endif  // V8_COMPRESS_POINTERS
    3572             : 
    3573             : }  // namespace compiler
    3574             : }  // namespace internal
    3575       79917 : }  // namespace v8

Generated by: LCOV version 1.10