LCOV - code coverage report
Current view: top level - src - code-stubs.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 430 466 92.3 %
Date: 2017-04-26 Functions: 89 99 89.9 %

          Line data    Source code
       1             : // Copyright 2012 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 "src/code-stubs.h"
       6             : 
       7             : #include <sstream>
       8             : 
       9             : #include "src/arguments.h"
      10             : #include "src/assembler-inl.h"
      11             : #include "src/ast/ast.h"
      12             : #include "src/bootstrapper.h"
      13             : #include "src/code-factory.h"
      14             : #include "src/code-stub-assembler.h"
      15             : #include "src/code-stubs-utils.h"
      16             : #include "src/counters.h"
      17             : #include "src/factory.h"
      18             : #include "src/gdb-jit.h"
      19             : #include "src/heap/heap-inl.h"
      20             : #include "src/ic/ic-stats.h"
      21             : #include "src/ic/ic.h"
      22             : #include "src/macro-assembler.h"
      23             : #include "src/objects-inl.h"
      24             : #include "src/tracing/tracing-category-observer.h"
      25             : 
      26             : namespace v8 {
      27             : namespace internal {
      28             : 
      29             : using compiler::CodeAssemblerState;
      30             : 
      31           0 : RUNTIME_FUNCTION(UnexpectedStubMiss) {
      32           0 :   FATAL("Unexpected deopt of a stub");
      33             :   return Smi::kZero;
      34             : }
      35             : 
      36       55168 : CodeStubDescriptor::CodeStubDescriptor(CodeStub* stub)
      37             :     : isolate_(stub->isolate()),
      38       55168 :       call_descriptor_(stub->GetCallInterfaceDescriptor()),
      39             :       stack_parameter_count_(no_reg),
      40             :       hint_stack_parameter_count_(-1),
      41             :       function_mode_(NOT_JS_FUNCTION_STUB_MODE),
      42             :       deoptimization_handler_(NULL),
      43             :       miss_handler_(),
      44      165504 :       has_miss_handler_(false) {
      45       55168 :   stub->InitializeDescriptor(this);
      46       55168 : }
      47             : 
      48       26647 : CodeStubDescriptor::CodeStubDescriptor(Isolate* isolate, uint32_t stub_key)
      49             :     : isolate_(isolate),
      50             :       stack_parameter_count_(no_reg),
      51             :       hint_stack_parameter_count_(-1),
      52             :       function_mode_(NOT_JS_FUNCTION_STUB_MODE),
      53             :       deoptimization_handler_(NULL),
      54             :       miss_handler_(),
      55       79941 :       has_miss_handler_(false) {
      56             :   CodeStub::InitializeDescriptor(isolate, stub_key, this);
      57       26647 : }
      58             : 
      59             : 
      60           0 : void CodeStubDescriptor::Initialize(Address deoptimization_handler,
      61             :                                     int hint_stack_parameter_count,
      62             :                                     StubFunctionMode function_mode) {
      63       81815 :   deoptimization_handler_ = deoptimization_handler;
      64       81815 :   hint_stack_parameter_count_ = hint_stack_parameter_count;
      65       81815 :   function_mode_ = function_mode;
      66           0 : }
      67             : 
      68             : 
      69           0 : void CodeStubDescriptor::Initialize(Register stack_parameter_count,
      70             :                                     Address deoptimization_handler,
      71             :                                     int hint_stack_parameter_count,
      72             :                                     StubFunctionMode function_mode) {
      73             :   Initialize(deoptimization_handler, hint_stack_parameter_count, function_mode);
      74           0 :   stack_parameter_count_ = stack_parameter_count;
      75           0 : }
      76             : 
      77             : 
      78    20038633 : bool CodeStub::FindCodeInCache(Code** code_out) {
      79    10019316 :   UnseededNumberDictionary* stubs = isolate()->heap()->code_stubs();
      80    10019317 :   int index = stubs->FindEntry(isolate(), GetKey());
      81    10019326 :   if (index != UnseededNumberDictionary::kNotFound) {
      82     9781673 :     *code_out = Code::cast(stubs->ValueAt(index));
      83     9781673 :     return true;
      84             :   }
      85             :   return false;
      86             : }
      87             : 
      88             : 
      89      859896 : void CodeStub::RecordCodeGeneration(Handle<Code> code) {
      90      286632 :   std::ostringstream os;
      91             :   os << *this;
      92      573264 :   PROFILE(isolate(),
      93             :           CodeCreateEvent(CodeEventListener::STUB_TAG,
      94             :                           AbstractCode::cast(*code), os.str().c_str()));
      95      286632 :   Counters* counters = isolate()->counters();
      96      286632 :   counters->total_stubs_code_size()->Increment(code->instruction_size());
      97             : #ifdef DEBUG
      98             :   code->VerifyEmbeddedObjects();
      99             : #endif
     100      286632 : }
     101             : 
     102             : 
     103      115304 : Code::Kind CodeStub::GetCodeKind() const {
     104      115304 :   return Code::STUB;
     105             : }
     106             : 
     107             : 
     108      110263 : Code::Flags CodeStub::GetCodeFlags() const {
     109      220526 :   return Code::ComputeFlags(GetCodeKind(), GetExtraICState());
     110             : }
     111             : 
     112       93648 : Handle<Code> CodeStub::GetCodeCopy(const FindAndReplacePattern& pattern) {
     113       46824 :   Handle<Code> ic = GetCode();
     114       46824 :   ic = isolate()->factory()->CopyCode(ic);
     115       46824 :   ic->FindAndReplace(pattern);
     116       46824 :   RecordCodeGeneration(ic);
     117       46824 :   return ic;
     118             : }
     119             : 
     120           0 : void CodeStub::DeleteStubFromCacheForTesting() {
     121           0 :   Heap* heap = isolate_->heap();
     122             :   Handle<UnseededNumberDictionary> dict(heap->code_stubs());
     123           0 :   dict = UnseededNumberDictionary::DeleteKey(dict, GetKey());
     124           0 :   heap->SetRootCodeStubs(*dict);
     125           0 : }
     126             : 
     127      129552 : Handle<Code> PlatformCodeStub::GenerateCode() {
     128      259104 :   Factory* factory = isolate()->factory();
     129             : 
     130             :   // Generate the new code.
     131      129552 :   MacroAssembler masm(isolate(), NULL, 256, CodeObjectRequired::kYes);
     132             : 
     133             :   {
     134             :     // Update the static counter each time a new code stub is generated.
     135      129552 :     isolate()->counters()->code_stubs()->Increment();
     136             : 
     137             :     // Generate the code for the stub.
     138             :     masm.set_generating_stub(true);
     139             :     // TODO(yangguo): remove this once we can serialize IC stubs.
     140             :     masm.enable_serializer();
     141             :     NoCurrentFrameScope scope(&masm);
     142      129552 :     Generate(&masm);
     143             :   }
     144             : 
     145             :   // Create the code object.
     146             :   CodeDesc desc;
     147      129552 :   masm.GetCode(&desc);
     148             :   // Copy the generated code into a heap object.
     149      129552 :   Code::Flags flags = Code::ComputeFlags(GetCodeKind(), GetExtraICState());
     150             :   Handle<Code> new_object = factory->NewCode(
     151      129552 :       desc, flags, masm.CodeObject(), NeedsImmovableCode());
     152      259104 :   return new_object;
     153             : }
     154             : 
     155             : 
     156    10474437 : Handle<Code> CodeStub::GetCode() {
     157    10232470 :   Heap* heap = isolate()->heap();
     158             :   Code* code;
     159     9994821 :   if (UseSpecialCache() ? FindCodeInSpecialCache(&code)
     160             :                         : FindCodeInCache(&code)) {
     161             :     DCHECK(GetCodeKind() == code->kind());
     162    19510048 :     return Handle<Code>(code);
     163             :   }
     164             : 
     165             :   {
     166             :     HandleScope scope(isolate());
     167             : 
     168      239808 :     Handle<Code> new_object = GenerateCode();
     169             :     new_object->set_stub_key(GetKey());
     170      239808 :     FinishCode(new_object);
     171      239808 :     RecordCodeGeneration(new_object);
     172             : 
     173             : #ifdef ENABLE_DISASSEMBLER
     174             :     if (FLAG_print_code_stubs) {
     175             :       CodeTracer::Scope trace_scope(isolate()->GetCodeTracer());
     176             :       OFStream os(trace_scope.file());
     177             :       std::ostringstream name;
     178             :       name << *this;
     179             :       new_object->Disassemble(name.str().c_str(), os);
     180             :       os << "\n";
     181             :     }
     182             : #endif
     183             : 
     184      239808 :     if (UseSpecialCache()) {
     185        2159 :       AddToSpecialCache(new_object);
     186             :     } else {
     187             :       // Update the dictionary and the root in Heap.
     188             :       Handle<UnseededNumberDictionary> dict =
     189             :           UnseededNumberDictionary::AtNumberPut(
     190             :               Handle<UnseededNumberDictionary>(heap->code_stubs()),
     191             :               GetKey(),
     192      237649 :               new_object);
     193      237649 :       heap->SetRootCodeStubs(*dict);
     194             :     }
     195      239808 :     code = *new_object;
     196             :   }
     197             : 
     198      239808 :   Activate(code);
     199             :   DCHECK(!NeedsImmovableCode() || Heap::IsImmovable(code) ||
     200             :          heap->code_space()->FirstPage()->Contains(code->address()));
     201      479616 :   return Handle<Code>(code, isolate());
     202             : }
     203             : 
     204             : 
     205      466529 : const char* CodeStub::MajorName(CodeStub::Major major_key) {
     206      466529 :   switch (major_key) {
     207             : #define DEF_CASE(name) case name: return #name "Stub";
     208       50691 :     CODE_STUB_LIST(DEF_CASE)
     209             : #undef DEF_CASE
     210             :     case NoCache:
     211           0 :       return "<NoCache>Stub";
     212             :     case NUMBER_OF_IDS:
     213           0 :       UNREACHABLE();
     214             :       return NULL;
     215             :   }
     216           0 :   return NULL;
     217             : }
     218             : 
     219             : 
     220      285557 : void CodeStub::PrintBaseName(std::ostream& os) const {  // NOLINT
     221      285557 :   os << MajorName(MajorKey());
     222      285557 : }
     223             : 
     224             : 
     225      285686 : void CodeStub::PrintName(std::ostream& os) const {  // NOLINT
     226      285686 :   PrintBaseName(os);
     227      285686 :   PrintState(os);
     228      285686 : }
     229             : 
     230             : 
     231       26928 : void CodeStub::Dispatch(Isolate* isolate, uint32_t key, void** value_out,
     232             :                         DispatchedCall call) {
     233       26928 :   switch (MajorKeyFromKey(key)) {
     234             : #define DEF_CASE(NAME)             \
     235             :   case NAME: {                     \
     236             :     NAME##Stub stub(key, isolate); \
     237             :     CodeStub* pstub = &stub;       \
     238             :     call(pstub, value_out);        \
     239             :     break;                         \
     240             :   }
     241       26928 :     CODE_STUB_LIST(DEF_CASE)
     242             : #undef DEF_CASE
     243             :     case NUMBER_OF_IDS:
     244             :     case NoCache:
     245           0 :       UNREACHABLE();
     246             :       break;
     247             :   }
     248       26928 : }
     249             : 
     250             : 
     251       26647 : static void InitializeDescriptorDispatchedCall(CodeStub* stub,
     252             :                                                void** value_out) {
     253             :   CodeStubDescriptor* descriptor_out =
     254             :       reinterpret_cast<CodeStubDescriptor*>(value_out);
     255       26647 :   stub->InitializeDescriptor(descriptor_out);
     256       53294 :   descriptor_out->set_call_descriptor(stub->GetCallInterfaceDescriptor());
     257       26647 : }
     258             : 
     259             : 
     260           0 : void CodeStub::InitializeDescriptor(Isolate* isolate, uint32_t key,
     261             :                                     CodeStubDescriptor* desc) {
     262             :   void** value_out = reinterpret_cast<void**>(desc);
     263       26647 :   Dispatch(isolate, key, value_out, &InitializeDescriptorDispatchedCall);
     264           0 : }
     265             : 
     266             : 
     267         281 : void CodeStub::GetCodeDispatchCall(CodeStub* stub, void** value_out) {
     268             :   Handle<Code>* code_out = reinterpret_cast<Handle<Code>*>(value_out);
     269             :   // Code stubs with special cache cannot be recreated from stub key.
     270         281 :   *code_out = stub->UseSpecialCache() ? Handle<Code>() : stub->GetCode();
     271         281 : }
     272             : 
     273             : 
     274         281 : MaybeHandle<Code> CodeStub::GetCode(Isolate* isolate, uint32_t key) {
     275             :   HandleScope scope(isolate);
     276             :   Handle<Code> code;
     277             :   void** value_out = reinterpret_cast<void**>(&code);
     278         281 :   Dispatch(isolate, key, value_out, &GetCodeDispatchCall);
     279         562 :   return scope.CloseAndEscape(code);
     280             : }
     281             : 
     282             : 
     283             : // static
     284          43 : void BinaryOpICStub::GenerateAheadOfTime(Isolate* isolate) {
     285          86 :   if (FLAG_minimal) return;
     286             :   // Generate the uninitialized versions of the stub.
     287         516 :   for (int op = Token::BIT_OR; op <= Token::MOD; ++op) {
     288         516 :     BinaryOpICStub stub(isolate, static_cast<Token::Value>(op));
     289         516 :     stub.GetCode();
     290             :   }
     291             : 
     292             :   // Generate special versions of the stub.
     293          43 :   BinaryOpICState::GenerateAheadOfTime(isolate, &GenerateAheadOfTime);
     294             : }
     295             : 
     296             : 
     297       10239 : void BinaryOpICStub::PrintState(std::ostream& os) const {  // NOLINT
     298       10239 :   os << state();
     299       10239 : }
     300             : 
     301             : 
     302             : // static
     303        4214 : void BinaryOpICStub::GenerateAheadOfTime(Isolate* isolate,
     304             :                                          const BinaryOpICState& state) {
     305        4214 :   if (FLAG_minimal) return;
     306             :   BinaryOpICStub stub(isolate, state);
     307        4214 :   stub.GetCode();
     308             : }
     309             : 
     310             : 
     311             : // static
     312          43 : void BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(Isolate* isolate) {
     313             :   // Generate special versions of the stub.
     314          43 :   BinaryOpICState::GenerateAheadOfTime(isolate, &GenerateAheadOfTime);
     315          43 : }
     316             : 
     317             : 
     318       50691 : void BinaryOpICWithAllocationSiteStub::PrintState(
     319             :     std::ostream& os) const {  // NOLINT
     320       50691 :   os << state();
     321       50691 : }
     322             : 
     323             : 
     324             : // static
     325        4214 : void BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(
     326        4214 :     Isolate* isolate, const BinaryOpICState& state) {
     327        4214 :   if (state.CouldCreateAllocationMementos()) {
     328             :     BinaryOpICWithAllocationSiteStub stub(isolate, state);
     329           0 :     stub.GetCode();
     330             :   }
     331        4214 : }
     332             : 
     333         129 : void StringAddStub::PrintBaseName(std::ostream& os) const {  // NOLINT
     334         129 :   os << "StringAddStub_" << flags() << "_" << pretenure_flag();
     335         129 : }
     336             : 
     337         516 : TF_STUB(StringAddStub, CodeStubAssembler) {
     338             :   StringAddFlags flags = stub->flags();
     339             :   PretenureFlag pretenure_flag = stub->pretenure_flag();
     340             : 
     341             :   Node* left = Parameter(Descriptor::kLeft);
     342             :   Node* right = Parameter(Descriptor::kRight);
     343             :   Node* context = Parameter(Descriptor::kContext);
     344             : 
     345         129 :   if ((flags & STRING_ADD_CHECK_LEFT) != 0) {
     346             :     DCHECK((flags & STRING_ADD_CONVERT) != 0);
     347             :     // TODO(danno): The ToString and JSReceiverToPrimitive below could be
     348             :     // combined to avoid duplicate smi and instance type checks.
     349          43 :     left = ToString(context, JSReceiverToPrimitive(context, left));
     350             :   }
     351         129 :   if ((flags & STRING_ADD_CHECK_RIGHT) != 0) {
     352             :     DCHECK((flags & STRING_ADD_CONVERT) != 0);
     353             :     // TODO(danno): The ToString and JSReceiverToPrimitive below could be
     354             :     // combined to avoid duplicate smi and instance type checks.
     355          43 :     right = ToString(context, JSReceiverToPrimitive(context, right));
     356             :   }
     357             : 
     358         129 :   if ((flags & STRING_ADD_CHECK_BOTH) == 0) {
     359             :     CodeStubAssembler::AllocationFlag allocation_flags =
     360             :         (pretenure_flag == TENURED) ? CodeStubAssembler::kPretenured
     361          43 :                                     : CodeStubAssembler::kNone;
     362          43 :     Return(StringAdd(context, left, right, allocation_flags));
     363             :   } else {
     364             :     Callable callable = CodeFactory::StringAdd(isolate(), STRING_ADD_CHECK_NONE,
     365          86 :                                                pretenure_flag);
     366          86 :     TailCallStub(callable, context, left, right);
     367             :   }
     368         129 : }
     369             : 
     370      818740 : InlineCacheState CompareICStub::GetICState() const {
     371             :   CompareICState::State state = Max(left(), right());
     372      818740 :   switch (state) {
     373             :     case CompareICState::UNINITIALIZED:
     374             :       return ::v8::internal::UNINITIALIZED;
     375             :     case CompareICState::BOOLEAN:
     376             :     case CompareICState::SMI:
     377             :     case CompareICState::NUMBER:
     378             :     case CompareICState::INTERNALIZED_STRING:
     379             :     case CompareICState::STRING:
     380             :     case CompareICState::UNIQUE_NAME:
     381             :     case CompareICState::RECEIVER:
     382             :     case CompareICState::KNOWN_RECEIVER:
     383      289086 :       return MONOMORPHIC;
     384             :     case CompareICState::GENERIC:
     385       24500 :       return ::v8::internal::GENERIC;
     386             :   }
     387           0 :   UNREACHABLE();
     388             :   return ::v8::internal::UNINITIALIZED;
     389             : }
     390             : 
     391             : 
     392       28590 : Condition CompareICStub::GetCondition() const {
     393       28590 :   return CompareIC::ComputeCondition(op());
     394             : }
     395             : 
     396             : 
     397       66854 : void CompareICStub::Generate(MacroAssembler* masm) {
     398       66854 :   switch (state()) {
     399             :     case CompareICState::UNINITIALIZED:
     400       23121 :       GenerateMiss(masm);
     401       23121 :       break;
     402             :     case CompareICState::BOOLEAN:
     403        2101 :       GenerateBooleans(masm);
     404        2101 :       break;
     405             :     case CompareICState::SMI:
     406       15291 :       GenerateSmis(masm);
     407       15291 :       break;
     408             :     case CompareICState::NUMBER:
     409        3424 :       GenerateNumbers(masm);
     410        3424 :       break;
     411             :     case CompareICState::STRING:
     412        3545 :       GenerateStrings(masm);
     413        3545 :       break;
     414             :     case CompareICState::INTERNALIZED_STRING:
     415        3376 :       GenerateInternalizedStrings(masm);
     416        3376 :       break;
     417             :     case CompareICState::UNIQUE_NAME:
     418          42 :       GenerateUniqueNames(masm);
     419          42 :       break;
     420             :     case CompareICState::RECEIVER:
     421         597 :       GenerateReceivers(masm);
     422         597 :       break;
     423             :     case CompareICState::KNOWN_RECEIVER:
     424             :       DCHECK(*known_map_ != NULL);
     425        2159 :       GenerateKnownReceivers(masm);
     426        2159 :       break;
     427             :     case CompareICState::GENERIC:
     428       13198 :       GenerateGeneric(masm);
     429       13198 :       break;
     430             :   }
     431       66854 : }
     432             : 
     433       78628 : Handle<Code> TurboFanCodeStub::GenerateCode() {
     434      157256 :   const char* name = CodeStub::MajorName(MajorKey());
     435       78628 :   Zone zone(isolate()->allocator(), ZONE_NAME);
     436       78628 :   CallInterfaceDescriptor descriptor(GetCallInterfaceDescriptor());
     437             :   compiler::CodeAssemblerState state(isolate(), &zone, descriptor,
     438      235884 :                                      GetCodeFlags(), name);
     439       78628 :   GenerateAssembly(&state);
     440      157256 :   return compiler::CodeAssembler::GenerateCode(&state);
     441             : }
     442             : 
     443       12828 : TF_STUB(ElementsTransitionAndStoreStub, CodeStubAssembler) {
     444             :   Node* receiver = Parameter(Descriptor::kReceiver);
     445             :   Node* key = Parameter(Descriptor::kName);
     446             :   Node* value = Parameter(Descriptor::kValue);
     447             :   Node* map = Parameter(Descriptor::kMap);
     448             :   Node* slot = Parameter(Descriptor::kSlot);
     449             :   Node* vector = Parameter(Descriptor::kVector);
     450             :   Node* context = Parameter(Descriptor::kContext);
     451             : 
     452             :   Comment(
     453             :       "ElementsTransitionAndStoreStub: from_kind=%s, to_kind=%s,"
     454             :       " is_jsarray=%d, store_mode=%d",
     455             :       ElementsKindToString(stub->from_kind()),
     456             :       ElementsKindToString(stub->to_kind()), stub->is_jsarray(),
     457        8552 :       stub->store_mode());
     458             : 
     459             :   Label miss(this);
     460             : 
     461             :   if (FLAG_trace_elements_transitions) {
     462             :     // Tracing elements transitions is the job of the runtime.
     463             :     Goto(&miss);
     464             :   } else {
     465             :     TransitionElementsKind(receiver, map, stub->from_kind(), stub->to_kind(),
     466        4276 :                            stub->is_jsarray(), &miss);
     467             :     EmitElementStore(receiver, key, value, stub->is_jsarray(), stub->to_kind(),
     468        2138 :                      stub->store_mode(), &miss);
     469        2138 :     Return(value);
     470             :   }
     471             : 
     472        2138 :   BIND(&miss);
     473             :   {
     474        2138 :     Comment("Miss");
     475             :     TailCallRuntime(Runtime::kElementsTransitionAndStoreIC_Miss, context,
     476        2138 :                     receiver, key, value, map, slot, vector);
     477        2138 :   }
     478        2138 : }
     479             : 
     480             : // TODO(ishell): move to builtins.
     481        1794 : TF_STUB(AllocateHeapNumberStub, CodeStubAssembler) {
     482         598 :   Node* result = AllocateHeapNumber();
     483         598 :   Return(result);
     484         598 : }
     485             : 
     486             : // TODO(ishell): move to builtins-handler-gen.
     487         228 : TF_STUB(StringLengthStub, CodeStubAssembler) {
     488             :   Node* value = Parameter(Descriptor::kReceiver);
     489          76 :   Node* string = LoadJSValueValue(value);
     490          76 :   Node* result = LoadStringLength(string);
     491          76 :   Return(result);
     492          76 : }
     493             : 
     494             : // TODO(ishell): move to builtins.
     495         129 : TF_STUB(NumberToStringStub, CodeStubAssembler) {
     496             :   Node* context = Parameter(Descriptor::kContext);
     497             :   Node* argument = Parameter(Descriptor::kArgument);
     498          43 :   Return(NumberToString(context, argument));
     499          43 : }
     500             : 
     501             : // TODO(ishell): move to builtins.
     502         129 : TF_STUB(SubStringStub, CodeStubAssembler) {
     503             :   Node* context = Parameter(Descriptor::kContext);
     504             :   Node* string = Parameter(Descriptor::kString);
     505             :   Node* from = Parameter(Descriptor::kFrom);
     506             :   Node* to = Parameter(Descriptor::kTo);
     507             : 
     508          43 :   Return(SubString(context, string, from, to));
     509          43 : }
     510             : 
     511             : // TODO(ishell): move to builtins-handler-gen.
     512        1050 : TF_STUB(KeyedLoadSloppyArgumentsStub, CodeStubAssembler) {
     513             :   Node* receiver = Parameter(Descriptor::kReceiver);
     514             :   Node* key = Parameter(Descriptor::kName);
     515             :   Node* slot = Parameter(Descriptor::kSlot);
     516             :   Node* vector = Parameter(Descriptor::kVector);
     517             :   Node* context = Parameter(Descriptor::kContext);
     518             : 
     519             :   Label miss(this);
     520             : 
     521         350 :   Node* result = LoadKeyedSloppyArguments(receiver, key, &miss);
     522         350 :   Return(result);
     523             : 
     524         350 :   BIND(&miss);
     525             :   {
     526         350 :     Comment("Miss");
     527             :     TailCallRuntime(Runtime::kKeyedLoadIC_Miss, context, receiver, key, slot,
     528         350 :                     vector);
     529         350 :   }
     530         350 : }
     531             : 
     532             : // TODO(ishell): move to builtins-handler-gen.
     533           0 : TF_STUB(KeyedStoreSloppyArgumentsStub, CodeStubAssembler) {
     534             :   Node* receiver = Parameter(Descriptor::kReceiver);
     535             :   Node* key = Parameter(Descriptor::kName);
     536             :   Node* value = Parameter(Descriptor::kValue);
     537             :   Node* slot = Parameter(Descriptor::kSlot);
     538             :   Node* vector = Parameter(Descriptor::kVector);
     539             :   Node* context = Parameter(Descriptor::kContext);
     540             : 
     541             :   Label miss(this);
     542             : 
     543           0 :   StoreKeyedSloppyArguments(receiver, key, value, &miss);
     544           0 :   Return(value);
     545             : 
     546           0 :   BIND(&miss);
     547             :   {
     548           0 :     Comment("Miss");
     549             :     TailCallRuntime(Runtime::kKeyedStoreIC_Miss, context, value, slot, vector,
     550           0 :                     receiver, key);
     551           0 :   }
     552           0 : }
     553             : 
     554       59844 : TF_STUB(LoadScriptContextFieldStub, CodeStubAssembler) {
     555             :   Comment("LoadScriptContextFieldStub: context_index=%d, slot=%d",
     556       59844 :           stub->context_index(), stub->slot_index());
     557             : 
     558             :   Node* context = Parameter(Descriptor::kContext);
     559             : 
     560       14961 :   Node* script_context = LoadScriptContext(context, stub->context_index());
     561       14961 :   Node* result = LoadFixedArrayElement(script_context, stub->slot_index());
     562       14961 :   Return(result);
     563       14961 : }
     564             : 
     565         124 : TF_STUB(StoreScriptContextFieldStub, CodeStubAssembler) {
     566             :   Comment("StoreScriptContextFieldStub: context_index=%d, slot=%d",
     567         124 :           stub->context_index(), stub->slot_index());
     568             : 
     569             :   Node* value = Parameter(Descriptor::kValue);
     570             :   Node* context = Parameter(Descriptor::kContext);
     571             : 
     572          31 :   Node* script_context = LoadScriptContext(context, stub->context_index());
     573             :   StoreFixedArrayElement(script_context, IntPtrConstant(stub->slot_index()),
     574          31 :                          value);
     575          31 :   Return(value);
     576          31 : }
     577             : 
     578             : // TODO(ishell): move to builtins-handler-gen.
     579         294 : TF_STUB(StoreInterceptorStub, CodeStubAssembler) {
     580             :   Node* receiver = Parameter(Descriptor::kReceiver);
     581             :   Node* name = Parameter(Descriptor::kName);
     582             :   Node* value = Parameter(Descriptor::kValue);
     583             :   Node* slot = Parameter(Descriptor::kSlot);
     584             :   Node* vector = Parameter(Descriptor::kVector);
     585             :   Node* context = Parameter(Descriptor::kContext);
     586             :   TailCallRuntime(Runtime::kStorePropertyWithInterceptor, context, value, slot,
     587          98 :                   vector, receiver, name);
     588          98 : }
     589             : 
     590             : // TODO(ishell): move to builtins-handler-gen.
     591         204 : TF_STUB(LoadIndexedInterceptorStub, CodeStubAssembler) {
     592             :   Node* receiver = Parameter(Descriptor::kReceiver);
     593             :   Node* key = Parameter(Descriptor::kName);
     594             :   Node* slot = Parameter(Descriptor::kSlot);
     595             :   Node* vector = Parameter(Descriptor::kVector);
     596             :   Node* context = Parameter(Descriptor::kContext);
     597             : 
     598          68 :   Label if_keyispositivesmi(this), if_keyisinvalid(this);
     599          68 :   Branch(TaggedIsPositiveSmi(key), &if_keyispositivesmi, &if_keyisinvalid);
     600          68 :   BIND(&if_keyispositivesmi);
     601          68 :   TailCallRuntime(Runtime::kLoadElementWithInterceptor, context, receiver, key);
     602             : 
     603          68 :   BIND(&if_keyisinvalid);
     604             :   TailCallRuntime(Runtime::kKeyedLoadIC_Miss, context, receiver, key, slot,
     605         136 :                   vector);
     606          68 : }
     607             : 
     608       54308 : void CallICStub::PrintState(std::ostream& os) const {  // NOLINT
     609       54308 :   os << convert_mode() << ", " << tail_call_mode();
     610       54308 : }
     611             : 
     612             : // TODO(ishell): Move to CallICAssembler.
     613      140740 : TF_STUB(CallICStub, CodeStubAssembler) {
     614             :   Node* context = Parameter(Descriptor::kContext);
     615             :   Node* target = Parameter(Descriptor::kTarget);
     616             :   Node* argc = Parameter(Descriptor::kActualArgumentsCount);
     617             :   Node* slot = Parameter(Descriptor::kSlot);
     618             :   Node* vector = Parameter(Descriptor::kVector);
     619             : 
     620             :   // TODO(bmeurer): The slot should actually be an IntPtr, but TurboFan's
     621             :   // SimplifiedLowering cannot deal with IntPtr machine type properly yet.
     622       28148 :   slot = ChangeInt32ToIntPtr(slot);
     623             : 
     624             :   // Static checks to assert it is safe to examine the type feedback element.
     625             :   // We don't know that we have a weak cell. We might have a private symbol
     626             :   // or an AllocationSite, but the memory is safe to examine.
     627             :   // AllocationSite::kTransitionInfoOffset - contains a Smi or pointer to
     628             :   // FixedArray.
     629             :   // WeakCell::kValueOffset - contains a JSFunction or Smi(0)
     630             :   // Symbol::kHashFieldSlot - if the low bit is 1, then the hash is not
     631             :   // computed, meaning that it can't appear to be a pointer. If the low bit is
     632             :   // 0, then hash is computed, but the 0 bit prevents the field from appearing
     633             :   // to be a pointer.
     634             :   STATIC_ASSERT(WeakCell::kSize >= kPointerSize);
     635             :   STATIC_ASSERT(AllocationSite::kTransitionInfoOffset ==
     636             :                     WeakCell::kValueOffset &&
     637             :                 WeakCell::kValueOffset == Symbol::kHashFieldSlot);
     638             : 
     639             :   // Increment the call count.
     640             :   // TODO(bmeurer): Would it be beneficial to use Int32Add on 64-bit?
     641       28148 :   Comment("increment call count");
     642       28148 :   Node* call_count = LoadFixedArrayElement(vector, slot, 1 * kPointerSize);
     643       28148 :   Node* new_count = SmiAdd(call_count, SmiConstant(1));
     644             :   // Count is Smi, so we don't need a write barrier.
     645             :   StoreFixedArrayElement(vector, slot, new_count, SKIP_WRITE_BARRIER,
     646       28148 :                          1 * kPointerSize);
     647             : 
     648       28148 :   Label call_function(this), extra_checks(this), call(this);
     649             : 
     650             :   // The checks. First, does function match the recorded monomorphic target?
     651       28148 :   Node* feedback_element = LoadFixedArrayElement(vector, slot);
     652       28148 :   Node* feedback_value = LoadWeakCellValueUnchecked(feedback_element);
     653       28148 :   Node* is_monomorphic = WordEqual(target, feedback_value);
     654       28148 :   GotoIfNot(is_monomorphic, &extra_checks);
     655             : 
     656             :   // The compare above could have been a SMI/SMI comparison. Guard against
     657             :   // this convincing us that we have a monomorphic JSFunction.
     658       28148 :   Node* is_smi = TaggedIsSmi(target);
     659       28148 :   Branch(is_smi, &extra_checks, &call_function);
     660             : 
     661       28148 :   BIND(&call_function);
     662             :   {
     663             :     // Call using CallFunction builtin.
     664             :     Callable callable = CodeFactory::CallFunction(
     665       28148 :         isolate(), stub->convert_mode(), stub->tail_call_mode());
     666       28148 :     TailCallStub(callable, context, target, argc);
     667             :   }
     668             : 
     669       28148 :   BIND(&extra_checks);
     670             :   {
     671       28148 :     Label check_initialized(this), mark_megamorphic(this),
     672       28148 :         create_allocation_site(this, Label::kDeferred),
     673       28148 :         create_weak_cell(this, Label::kDeferred);
     674             : 
     675       28148 :     Comment("check if megamorphic");
     676             :     // Check if it is a megamorphic target.
     677             :     Node* is_megamorphic =
     678             :         WordEqual(feedback_element,
     679       56296 :                   HeapConstant(FeedbackVector::MegamorphicSentinel(isolate())));
     680       28148 :     GotoIf(is_megamorphic, &call);
     681             : 
     682       28148 :     Comment("check if it is an allocation site");
     683             :     GotoIfNot(IsAllocationSiteMap(LoadMap(feedback_element)),
     684       28148 :               &check_initialized);
     685             : 
     686             :     // If it is not the Array() function, mark megamorphic.
     687             :     Node* context_slot = LoadContextElement(LoadNativeContext(context),
     688       28148 :                                             Context::ARRAY_FUNCTION_INDEX);
     689       28148 :     Node* is_array_function = WordEqual(context_slot, target);
     690       28148 :     GotoIfNot(is_array_function, &mark_megamorphic);
     691             : 
     692             :     // Call ArrayConstructorStub.
     693       28148 :     Callable callable = CodeFactory::ArrayConstructor(isolate());
     694       28148 :     TailCallStub(callable, context, target, target, argc, feedback_element);
     695             : 
     696       28148 :     BIND(&check_initialized);
     697             :     {
     698       28148 :       Comment("check if uninitialized");
     699             :       // Check if it is uninitialized target first.
     700             :       Node* is_uninitialized = WordEqual(
     701             :           feedback_element,
     702       56296 :           HeapConstant(FeedbackVector::UninitializedSentinel(isolate())));
     703       28148 :       GotoIfNot(is_uninitialized, &mark_megamorphic);
     704             : 
     705       28148 :       Comment("handle unitinitialized");
     706             :       // If it is not a JSFunction mark it as megamorphic.
     707       28148 :       Node* is_smi = TaggedIsSmi(target);
     708       28148 :       GotoIf(is_smi, &mark_megamorphic);
     709             : 
     710             :       // Check if function is an object of JSFunction type.
     711       28148 :       Node* is_js_function = IsJSFunction(target);
     712       28148 :       GotoIfNot(is_js_function, &mark_megamorphic);
     713             : 
     714             :       // Check if it is the Array() function.
     715             :       Node* context_slot = LoadContextElement(LoadNativeContext(context),
     716       28148 :                                               Context::ARRAY_FUNCTION_INDEX);
     717       28148 :       Node* is_array_function = WordEqual(context_slot, target);
     718       28148 :       GotoIf(is_array_function, &create_allocation_site);
     719             : 
     720             :       // Check if the function belongs to the same native context.
     721             :       Node* native_context = LoadNativeContext(
     722       28148 :           LoadObjectField(target, JSFunction::kContextOffset));
     723             :       Node* is_same_native_context =
     724       28148 :           WordEqual(native_context, LoadNativeContext(context));
     725       28148 :       Branch(is_same_native_context, &create_weak_cell, &mark_megamorphic);
     726             :     }
     727             : 
     728       28148 :     BIND(&create_weak_cell);
     729             :     {
     730             :       // Wrap the {target} in a WeakCell and remember it.
     731       28148 :       Comment("create weak cell");
     732       28148 :       CreateWeakCellInFeedbackVector(vector, SmiTag(slot), target);
     733             : 
     734             :       // Call using CallFunction builtin.
     735       28148 :       Goto(&call_function);
     736             :     }
     737             : 
     738       28148 :     BIND(&create_allocation_site);
     739             :     {
     740             :       // Create an AllocationSite for the {target}.
     741       28148 :       Comment("create allocation site");
     742       28148 :       CreateAllocationSiteInFeedbackVector(vector, SmiTag(slot));
     743             : 
     744             :       // Call using CallFunction builtin. CallICs have a PREMONOMORPHIC state.
     745             :       // They start collecting feedback only when a call is executed the second
     746             :       // time. So, do not pass any feedback here.
     747       28148 :       Goto(&call_function);
     748             :     }
     749             : 
     750       28148 :     BIND(&mark_megamorphic);
     751             :     {
     752             :       // Mark it as a megamorphic.
     753             :       // MegamorphicSentinel is created as a part of Heap::InitialObjects
     754             :       // and will not move during a GC. So it is safe to skip write barrier.
     755             :       DCHECK(Heap::RootIsImmortalImmovable(Heap::kmegamorphic_symbolRootIndex));
     756             :       StoreFixedArrayElement(
     757             :           vector, slot,
     758             :           HeapConstant(FeedbackVector::MegamorphicSentinel(isolate())),
     759       56296 :           SKIP_WRITE_BARRIER);
     760       28148 :       Goto(&call);
     761       28148 :     }
     762             :   }
     763             : 
     764       28148 :   BIND(&call);
     765             :   {
     766             :     // Call using call builtin.
     767       28148 :     Comment("call using Call builtin");
     768             :     Callable callable_call = CodeFactory::Call(isolate(), stub->convert_mode(),
     769       28148 :                                                stub->tail_call_mode());
     770       28148 :     TailCallStub(callable_call, context, target, argc);
     771       28148 :   }
     772       28148 : }
     773             : 
     774       78480 : TF_STUB(CallICTrampolineStub, CodeStubAssembler) {
     775             :   Node* context = Parameter(Descriptor::kContext);
     776             :   Node* target = Parameter(Descriptor::kTarget);
     777             :   Node* argc = Parameter(Descriptor::kActualArgumentsCount);
     778             :   Node* slot = Parameter(Descriptor::kSlot);
     779       26159 :   Node* vector = LoadFeedbackVectorForStub();
     780             : 
     781             :   Callable callable = CodeFactory::CallIC(isolate(), stub->convert_mode(),
     782       52320 :                                           stub->tail_call_mode());
     783       26160 :   TailCallStub(callable, context, target, argc, slot, vector);
     784       26160 : }
     785             : 
     786          86 : void JSEntryStub::FinishCode(Handle<Code> code) {
     787             :   Handle<FixedArray> handler_table =
     788          86 :       code->GetIsolate()->factory()->NewFixedArray(1, TENURED);
     789          86 :   handler_table->set(0, Smi::FromInt(handler_offset_));
     790          86 :   code->set_handler_table(*handler_table);
     791          86 : }
     792             : 
     793         220 : void TransitionElementsKindStub::InitializeDescriptor(
     794             :     CodeStubDescriptor* descriptor) {
     795             :   descriptor->Initialize(
     796         220 :       Runtime::FunctionForId(Runtime::kTransitionElementsKind)->entry);
     797         220 : }
     798             : 
     799             : 
     800           0 : void AllocateHeapNumberStub::InitializeDescriptor(
     801             :     CodeStubDescriptor* descriptor) {
     802             :   descriptor->Initialize(
     803           0 :       Runtime::FunctionForId(Runtime::kAllocateHeapNumber)->entry);
     804           0 : }
     805             : 
     806             : 
     807       45324 : void ToBooleanICStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
     808             :   descriptor->Initialize(FUNCTION_ADDR(Runtime_ToBooleanIC_Miss));
     809       45324 :   descriptor->SetMissHandler(Runtime::kToBooleanIC_Miss);
     810       45324 : }
     811             : 
     812             : 
     813       28076 : void BinaryOpICStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
     814             :   descriptor->Initialize(FUNCTION_ADDR(Runtime_BinaryOpIC_Miss));
     815       28076 :   descriptor->SetMissHandler(Runtime::kBinaryOpIC_Miss);
     816       28076 : }
     817             : 
     818             : 
     819        8195 : void BinaryOpWithAllocationSiteStub::InitializeDescriptor(
     820             :     CodeStubDescriptor* descriptor) {
     821             :   descriptor->Initialize(
     822             :       FUNCTION_ADDR(Runtime_BinaryOpIC_MissWithAllocationSite));
     823        8195 : }
     824             : 
     825             : // TODO(ishell): move to builtins.
     826         172 : TF_STUB(GetPropertyStub, CodeStubAssembler) {
     827          86 :   Label call_runtime(this, Label::kDeferred), return_undefined(this), end(this);
     828             : 
     829             :   Node* object = Parameter(Descriptor::kObject);
     830             :   Node* key = Parameter(Descriptor::kKey);
     831             :   Node* context = Parameter(Descriptor::kContext);
     832          86 :   VARIABLE(var_result, MachineRepresentation::kTagged);
     833             : 
     834             :   CodeStubAssembler::LookupInHolder lookup_property_in_holder =
     835             :       [=, &var_result, &end](Node* receiver, Node* holder, Node* holder_map,
     836             :                              Node* holder_instance_type, Node* unique_name,
     837          43 :                              Label* next_holder, Label* if_bailout) {
     838          43 :         VARIABLE(var_value, MachineRepresentation::kTagged);
     839          86 :         Label if_found(this);
     840             :         TryGetOwnProperty(context, receiver, holder, holder_map,
     841             :                           holder_instance_type, unique_name, &if_found,
     842          43 :                           &var_value, next_holder, if_bailout);
     843          43 :         BIND(&if_found);
     844             :         {
     845          43 :           var_result.Bind(var_value.value());
     846          43 :           Goto(&end);
     847             :         }
     848          43 :       };
     849             : 
     850             :   CodeStubAssembler::LookupInHolder lookup_element_in_holder =
     851             :       [=](Node* receiver, Node* holder, Node* holder_map,
     852             :           Node* holder_instance_type, Node* index, Label* next_holder,
     853             :           Label* if_bailout) {
     854             :         // Not supported yet.
     855          43 :         Use(next_holder);
     856          43 :         Goto(if_bailout);
     857             :       };
     858             : 
     859             :   TryPrototypeChainLookup(object, key, lookup_property_in_holder,
     860             :                           lookup_element_in_holder, &return_undefined,
     861          43 :                           &call_runtime);
     862             : 
     863          43 :   BIND(&return_undefined);
     864             :   {
     865          43 :     var_result.Bind(UndefinedConstant());
     866          43 :     Goto(&end);
     867             :   }
     868             : 
     869          43 :   BIND(&call_runtime);
     870             :   {
     871          43 :     var_result.Bind(CallRuntime(Runtime::kGetProperty, context, object, key));
     872          43 :     Goto(&end);
     873             :   }
     874             : 
     875          43 :   BIND(&end);
     876          86 :   Return(var_result.value());
     877          43 : }
     878             : 
     879          43 : void CreateAllocationSiteStub::GenerateAheadOfTime(Isolate* isolate) {
     880             :   CreateAllocationSiteStub stub(isolate);
     881          43 :   stub.GetCode();
     882          43 : }
     883             : 
     884             : 
     885          43 : void CreateWeakCellStub::GenerateAheadOfTime(Isolate* isolate) {
     886             :   CreateWeakCellStub stub(isolate);
     887          43 :   stub.GetCode();
     888          43 : }
     889             : 
     890             : // TODO(ishell): move to builtins-handler-gen.
     891        1929 : TF_STUB(StoreSlowElementStub, CodeStubAssembler) {
     892             :   Node* receiver = Parameter(Descriptor::kReceiver);
     893             :   Node* name = Parameter(Descriptor::kName);
     894             :   Node* value = Parameter(Descriptor::kValue);
     895             :   Node* slot = Parameter(Descriptor::kSlot);
     896             :   Node* vector = Parameter(Descriptor::kVector);
     897             :   Node* context = Parameter(Descriptor::kContext);
     898             : 
     899             :   TailCallRuntime(Runtime::kKeyedStoreIC_Slow, context, value, slot, vector,
     900         643 :                   receiver, name);
     901         643 : }
     902             : 
     903       23064 : TF_STUB(StoreFastElementStub, CodeStubAssembler) {
     904             :   Comment("StoreFastElementStub: js_array=%d, elements_kind=%s, store_mode=%d",
     905             :           stub->is_js_array(), ElementsKindToString(stub->elements_kind()),
     906       11532 :           stub->store_mode());
     907             : 
     908             :   Node* receiver = Parameter(Descriptor::kReceiver);
     909             :   Node* key = Parameter(Descriptor::kName);
     910             :   Node* value = Parameter(Descriptor::kValue);
     911             :   Node* slot = Parameter(Descriptor::kSlot);
     912             :   Node* vector = Parameter(Descriptor::kVector);
     913             :   Node* context = Parameter(Descriptor::kContext);
     914             : 
     915             :   Label miss(this);
     916             : 
     917             :   EmitElementStore(receiver, key, value, stub->is_js_array(),
     918        3844 :                    stub->elements_kind(), stub->store_mode(), &miss);
     919        3844 :   Return(value);
     920             : 
     921        3844 :   BIND(&miss);
     922             :   {
     923        3844 :     Comment("Miss");
     924             :     TailCallRuntime(Runtime::kKeyedStoreIC_Miss, context, value, slot, vector,
     925        3844 :                     receiver, key);
     926        3844 :   }
     927        3844 : }
     928             : 
     929             : // static
     930          43 : void StoreFastElementStub::GenerateAheadOfTime(Isolate* isolate) {
     931          86 :   if (FLAG_minimal) return;
     932             :   StoreFastElementStub(isolate, false, FAST_HOLEY_ELEMENTS, STANDARD_STORE)
     933          86 :       .GetCode();
     934             :   StoreFastElementStub(isolate, false, FAST_HOLEY_ELEMENTS,
     935          86 :                        STORE_AND_GROW_NO_TRANSITION).GetCode();
     936         301 :   for (int i = FIRST_FAST_ELEMENTS_KIND; i <= LAST_FAST_ELEMENTS_KIND; i++) {
     937         258 :     ElementsKind kind = static_cast<ElementsKind>(i);
     938         516 :     StoreFastElementStub(isolate, true, kind, STANDARD_STORE).GetCode();
     939             :     StoreFastElementStub(isolate, true, kind, STORE_AND_GROW_NO_TRANSITION)
     940         516 :         .GetCode();
     941             :   }
     942             : }
     943             : 
     944      130693 : bool ToBooleanICStub::UpdateStatus(Handle<Object> object) {
     945             :   ToBooleanHints old_hints = hints();
     946             :   ToBooleanHints new_hints = old_hints;
     947             :   bool to_boolean_value = false;  // Dummy initialization.
     948      367680 :   if (object->IsUndefined(isolate())) {
     949             :     new_hints |= ToBooleanHint::kUndefined;
     950             :     to_boolean_value = false;
     951      106294 :   } else if (object->IsBoolean()) {
     952             :     new_hints |= ToBooleanHint::kBoolean;
     953             :     to_boolean_value = object->IsTrue(isolate());
     954       55693 :   } else if (object->IsNull(isolate())) {
     955             :     new_hints |= ToBooleanHint::kNull;
     956             :     to_boolean_value = false;
     957       53709 :   } else if (object->IsSmi()) {
     958             :     new_hints |= ToBooleanHint::kSmallInteger;
     959       12976 :     to_boolean_value = Smi::cast(*object)->value() != 0;
     960       40733 :   } else if (object->IsJSReceiver()) {
     961             :     new_hints |= ToBooleanHint::kReceiver;
     962       33883 :     to_boolean_value = !object->IsUndetectable();
     963        6850 :   } else if (object->IsString()) {
     964             :     DCHECK(!object->IsUndetectable());
     965             :     new_hints |= ToBooleanHint::kString;
     966        6737 :     to_boolean_value = String::cast(*object)->length() != 0;
     967         113 :   } else if (object->IsSymbol()) {
     968             :     new_hints |= ToBooleanHint::kSymbol;
     969             :     to_boolean_value = true;
     970          76 :   } else if (object->IsHeapNumber()) {
     971             :     DCHECK(!object->IsUndetectable());
     972             :     new_hints |= ToBooleanHint::kHeapNumber;
     973             :     double value = HeapNumber::cast(*object)->value();
     974          76 :     to_boolean_value = value != 0 && !std::isnan(value);
     975             :   } else {
     976             :     // We should never see an internal object at runtime here!
     977           0 :     UNREACHABLE();
     978             :     to_boolean_value = true;
     979             :   }
     980             : 
     981      130693 :   set_sub_minor_key(HintsBits::update(sub_minor_key(), new_hints));
     982      130693 :   return to_boolean_value;
     983             : }
     984             : 
     985       21342 : void ToBooleanICStub::PrintState(std::ostream& os) const {  // NOLINT
     986       21342 :   os << hints();
     987       21342 : }
     988             : 
     989       60686 : void StubFailureTrampolineStub::GenerateAheadOfTime(Isolate* isolate) {
     990             :   StubFailureTrampolineStub stub1(isolate, NOT_JS_FUNCTION_STUB_MODE);
     991             :   StubFailureTrampolineStub stub2(isolate, JS_FUNCTION_STUB_MODE);
     992       60686 :   stub1.GetCode();
     993       60686 :   stub2.GetCode();
     994       60686 : }
     995             : 
     996             : 
     997           0 : void ProfileEntryHookStub::EntryHookTrampoline(intptr_t function,
     998             :                                                intptr_t stack_pointer,
     999           0 :                                                Isolate* isolate) {
    1000             :   FunctionEntryHook entry_hook = isolate->function_entry_hook();
    1001             :   DCHECK(entry_hook != NULL);
    1002           0 :   entry_hook(function, stack_pointer);
    1003           0 : }
    1004             : 
    1005             : // TODO(ishell): move to builtins.
    1006         129 : TF_STUB(CreateAllocationSiteStub, CodeStubAssembler) {
    1007             :   Return(CreateAllocationSiteInFeedbackVector(Parameter(Descriptor::kVector),
    1008          43 :                                               Parameter(Descriptor::kSlot)));
    1009          43 : }
    1010             : 
    1011             : // TODO(ishell): move to builtins.
    1012         129 : TF_STUB(CreateWeakCellStub, CodeStubAssembler) {
    1013             :   Return(CreateWeakCellInFeedbackVector(Parameter(Descriptor::kVector),
    1014             :                                         Parameter(Descriptor::kSlot),
    1015          43 :                                         Parameter(Descriptor::kValue)));
    1016          43 : }
    1017             : 
    1018        1462 : TF_STUB(ArrayNoArgumentConstructorStub, CodeStubAssembler) {
    1019             :   ElementsKind elements_kind = stub->elements_kind();
    1020             :   Node* native_context = LoadObjectField(Parameter(Descriptor::kFunction),
    1021         344 :                                          JSFunction::kContextOffset);
    1022             :   bool track_allocation_site =
    1023         516 :       AllocationSite::GetMode(elements_kind) == TRACK_ALLOCATION_SITE &&
    1024             :       stub->override_mode() != DISABLE_ALLOCATION_SITES;
    1025             :   Node* allocation_site =
    1026         344 :       track_allocation_site ? Parameter(Descriptor::kAllocationSite) : nullptr;
    1027         344 :   Node* array_map = LoadJSArrayElementsMap(elements_kind, native_context);
    1028             :   Node* array =
    1029             :       AllocateJSArray(elements_kind, array_map,
    1030             :                       IntPtrConstant(JSArray::kPreallocatedArrayElements),
    1031         344 :                       SmiConstant(Smi::kZero), allocation_site);
    1032         344 :   Return(array);
    1033         344 : }
    1034             : 
    1035         258 : TF_STUB(InternalArrayNoArgumentConstructorStub, CodeStubAssembler) {
    1036             :   Node* array_map = LoadObjectField(Parameter(Descriptor::kFunction),
    1037          86 :                                     JSFunction::kPrototypeOrInitialMapOffset);
    1038             :   Node* array =
    1039             :       AllocateJSArray(stub->elements_kind(), array_map,
    1040             :                       IntPtrConstant(JSArray::kPreallocatedArrayElements),
    1041         172 :                       SmiConstant(Smi::kZero));
    1042          86 :   Return(array);
    1043          86 : }
    1044             : 
    1045             : class ArrayConstructorAssembler : public CodeStubAssembler {
    1046             :  public:
    1047             :   typedef compiler::Node Node;
    1048             : 
    1049             :   explicit ArrayConstructorAssembler(compiler::CodeAssemblerState* state)
    1050         430 :       : CodeStubAssembler(state) {}
    1051             : 
    1052             :   void GenerateConstructor(Node* context, Node* array_function, Node* array_map,
    1053             :                            Node* array_size, Node* allocation_site,
    1054             :                            ElementsKind elements_kind, AllocationSiteMode mode);
    1055             : };
    1056             : 
    1057         430 : void ArrayConstructorAssembler::GenerateConstructor(
    1058             :     Node* context, Node* array_function, Node* array_map, Node* array_size,
    1059             :     Node* allocation_site, ElementsKind elements_kind,
    1060             :     AllocationSiteMode mode) {
    1061         430 :   Label ok(this);
    1062         430 :   Label smi_size(this);
    1063         430 :   Label small_smi_size(this);
    1064         430 :   Label call_runtime(this, Label::kDeferred);
    1065             : 
    1066         430 :   Branch(TaggedIsSmi(array_size), &smi_size, &call_runtime);
    1067             : 
    1068         430 :   BIND(&smi_size);
    1069             : 
    1070         430 :   if (IsFastPackedElementsKind(elements_kind)) {
    1071             :     Label abort(this, Label::kDeferred);
    1072             :     Branch(SmiEqual(array_size, SmiConstant(Smi::kZero)), &small_smi_size,
    1073         215 :            &abort);
    1074             : 
    1075         215 :     BIND(&abort);
    1076         215 :     Node* reason = SmiConstant(Smi::FromInt(kAllocatingNonEmptyPackedArray));
    1077         215 :     TailCallRuntime(Runtime::kAbort, context, reason);
    1078             :   } else {
    1079             :     int element_size =
    1080             :         IsFastDoubleElementsKind(elements_kind) ? kDoubleSize : kPointerSize;
    1081             :     int max_fast_elements =
    1082             :         (kMaxRegularHeapObjectSize - FixedArray::kHeaderSize - JSArray::kSize -
    1083             :          AllocationMemento::kSize) /
    1084             :         element_size;
    1085             :     Branch(SmiAboveOrEqual(array_size,
    1086             :                            SmiConstant(Smi::FromInt(max_fast_elements))),
    1087         215 :            &call_runtime, &small_smi_size);
    1088             :   }
    1089             : 
    1090         430 :   BIND(&small_smi_size);
    1091             :   {
    1092             :     Node* array = AllocateJSArray(
    1093             :         elements_kind, array_map, array_size, array_size,
    1094             :         mode == DONT_TRACK_ALLOCATION_SITE ? nullptr : allocation_site,
    1095         430 :         CodeStubAssembler::SMI_PARAMETERS);
    1096         430 :     Return(array);
    1097             :   }
    1098             : 
    1099         430 :   BIND(&call_runtime);
    1100             :   {
    1101             :     TailCallRuntime(Runtime::kNewArray, context, array_function, array_size,
    1102         430 :                     array_function, allocation_site);
    1103         430 :   }
    1104         430 : }
    1105             : 
    1106        2064 : TF_STUB(ArraySingleArgumentConstructorStub, ArrayConstructorAssembler) {
    1107             :   ElementsKind elements_kind = stub->elements_kind();
    1108             :   Node* context = Parameter(Descriptor::kContext);
    1109             :   Node* function = Parameter(Descriptor::kFunction);
    1110         344 :   Node* native_context = LoadObjectField(function, JSFunction::kContextOffset);
    1111         344 :   Node* array_map = LoadJSArrayElementsMap(elements_kind, native_context);
    1112             :   AllocationSiteMode mode = stub->override_mode() == DISABLE_ALLOCATION_SITES
    1113             :                                 ? DONT_TRACK_ALLOCATION_SITE
    1114         344 :                                 : AllocationSite::GetMode(elements_kind);
    1115             :   Node* array_size = Parameter(Descriptor::kArraySizeSmiParameter);
    1116             :   Node* allocation_site = Parameter(Descriptor::kAllocationSite);
    1117             : 
    1118             :   GenerateConstructor(context, function, array_map, array_size, allocation_site,
    1119         344 :                       elements_kind, mode);
    1120         344 : }
    1121             : 
    1122         430 : TF_STUB(InternalArraySingleArgumentConstructorStub, ArrayConstructorAssembler) {
    1123             :   Node* context = Parameter(Descriptor::kContext);
    1124             :   Node* function = Parameter(Descriptor::kFunction);
    1125             :   Node* array_map =
    1126          86 :       LoadObjectField(function, JSFunction::kPrototypeOrInitialMapOffset);
    1127             :   Node* array_size = Parameter(Descriptor::kArraySizeSmiParameter);
    1128          86 :   Node* allocation_site = UndefinedConstant();
    1129             : 
    1130             :   GenerateConstructor(context, function, array_map, array_size, allocation_site,
    1131          86 :                       stub->elements_kind(), DONT_TRACK_ALLOCATION_SITE);
    1132          86 : }
    1133             : 
    1134        1236 : TF_STUB(GrowArrayElementsStub, CodeStubAssembler) {
    1135         309 :   Label runtime(this, CodeStubAssembler::Label::kDeferred);
    1136             : 
    1137             :   Node* object = Parameter(Descriptor::kObject);
    1138             :   Node* key = Parameter(Descriptor::kKey);
    1139             :   Node* context = Parameter(Descriptor::kContext);
    1140             :   ElementsKind kind = stub->elements_kind();
    1141             : 
    1142         309 :   Node* elements = LoadElements(object);
    1143             :   Node* new_elements =
    1144         309 :       TryGrowElementsCapacity(object, elements, kind, key, &runtime);
    1145         309 :   Return(new_elements);
    1146             : 
    1147         309 :   BIND(&runtime);
    1148             :   // TODO(danno): Make this a tail call when the stub is only used from TurboFan
    1149             :   // code. This musn't be a tail call for now, since the caller site in lithium
    1150             :   // creates a safepoint. This safepoint musn't have a different number of
    1151             :   // arguments on the stack in the case that a GC happens from the slow-case
    1152             :   // allocation path (zero, since all the stubs inputs are in registers) and
    1153             :   // when the call happens (it would be two in the tail call case due to the
    1154             :   // tail call pushing the arguments on the stack for the runtime call). By not
    1155             :   // tail-calling, the runtime call case also has zero arguments on the stack
    1156             :   // for the stub frame.
    1157         309 :   Return(CallRuntime(Runtime::kGrowArrayElements, context, object, key));
    1158         309 : }
    1159             : 
    1160       28313 : ArrayConstructorStub::ArrayConstructorStub(Isolate* isolate)
    1161       28313 :     : PlatformCodeStub(isolate) {}
    1162             : 
    1163         280 : InternalArrayConstructorStub::InternalArrayConstructorStub(Isolate* isolate)
    1164         280 :     : PlatformCodeStub(isolate) {}
    1165             : 
    1166             : }  // namespace internal
    1167             : }  // namespace v8

Generated by: LCOV version 1.10