LCOV - code coverage report
Current view: top level - test/cctest - test-code-stub-assembler.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 1762 1775 99.3 %
Date: 2019-02-19 Functions: 101 103 98.1 %

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

Generated by: LCOV version 1.10