LCOV - code coverage report
Current view: top level - test/cctest - test-code-stub-assembler.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 1549 1552 99.8 %
Date: 2017-10-20 Functions: 93 94 98.9 %

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

Generated by: LCOV version 1.10