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

Generated by: LCOV version 1.10