Home | History | Annotate | Download | only in interpreter
      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 "src/interpreter/interpreter.h"
      6 
      7 #include <fstream>
      8 #include <memory>
      9 
     10 #include "src/ast/prettyprinter.h"
     11 #include "src/code-factory.h"
     12 #include "src/compilation-info.h"
     13 #include "src/compiler.h"
     14 #include "src/factory.h"
     15 #include "src/interpreter/bytecode-flags.h"
     16 #include "src/interpreter/bytecode-generator.h"
     17 #include "src/interpreter/bytecodes.h"
     18 #include "src/interpreter/interpreter-assembler.h"
     19 #include "src/interpreter/interpreter-intrinsics.h"
     20 #include "src/log.h"
     21 #include "src/zone/zone.h"
     22 
     23 namespace v8 {
     24 namespace internal {
     25 namespace interpreter {
     26 
     27 using compiler::Node;
     28 typedef CodeStubAssembler::Label Label;
     29 typedef CodeStubAssembler::Variable Variable;
     30 typedef InterpreterAssembler::Arg Arg;
     31 
     32 #define __ assembler->
     33 
     34 class InterpreterCompilationJob final : public CompilationJob {
     35  public:
     36   explicit InterpreterCompilationJob(CompilationInfo* info);
     37 
     38  protected:
     39   Status PrepareJobImpl() final;
     40   Status ExecuteJobImpl() final;
     41   Status FinalizeJobImpl() final;
     42 
     43  private:
     44   BytecodeGenerator* generator() { return &generator_; }
     45 
     46   BytecodeGenerator generator_;
     47 
     48   DISALLOW_COPY_AND_ASSIGN(InterpreterCompilationJob);
     49 };
     50 
     51 Interpreter::Interpreter(Isolate* isolate) : isolate_(isolate) {
     52   memset(dispatch_table_, 0, sizeof(dispatch_table_));
     53 }
     54 
     55 void Interpreter::Initialize() {
     56   if (!ShouldInitializeDispatchTable()) return;
     57   Zone zone(isolate_->allocator(), ZONE_NAME);
     58   HandleScope scope(isolate_);
     59 
     60   if (FLAG_trace_ignition_dispatches) {
     61     static const int kBytecodeCount = static_cast<int>(Bytecode::kLast) + 1;
     62     bytecode_dispatch_counters_table_.reset(
     63         new uintptr_t[kBytecodeCount * kBytecodeCount]);
     64     memset(bytecode_dispatch_counters_table_.get(), 0,
     65            sizeof(uintptr_t) * kBytecodeCount * kBytecodeCount);
     66   }
     67 
     68   // Generate bytecode handlers for all bytecodes and scales.
     69   const OperandScale kOperandScales[] = {
     70 #define VALUE(Name, _) OperandScale::k##Name,
     71       OPERAND_SCALE_LIST(VALUE)
     72 #undef VALUE
     73   };
     74 
     75   for (OperandScale operand_scale : kOperandScales) {
     76 #define GENERATE_CODE(Name, ...)                                               \
     77   {                                                                            \
     78     if (Bytecodes::BytecodeHasHandler(Bytecode::k##Name, operand_scale)) {     \
     79       InterpreterAssembler assembler(isolate_, &zone, Bytecode::k##Name,       \
     80                                      operand_scale);                           \
     81       Do##Name(&assembler);                                                    \
     82       Handle<Code> code = assembler.GenerateCode();                            \
     83       size_t index = GetDispatchTableIndex(Bytecode::k##Name, operand_scale);  \
     84       dispatch_table_[index] = code->entry();                                  \
     85       TraceCodegen(code);                                                      \
     86       PROFILE(                                                                 \
     87           isolate_,                                                            \
     88           CodeCreateEvent(                                                     \
     89               CodeEventListener::BYTECODE_HANDLER_TAG,                         \
     90               AbstractCode::cast(*code),                                       \
     91               Bytecodes::ToString(Bytecode::k##Name, operand_scale).c_str())); \
     92     }                                                                          \
     93   }
     94     BYTECODE_LIST(GENERATE_CODE)
     95 #undef GENERATE_CODE
     96   }
     97 
     98   // Fill unused entries will the illegal bytecode handler.
     99   size_t illegal_index =
    100       GetDispatchTableIndex(Bytecode::kIllegal, OperandScale::kSingle);
    101   for (size_t index = 0; index < arraysize(dispatch_table_); ++index) {
    102     if (dispatch_table_[index] == nullptr) {
    103       dispatch_table_[index] = dispatch_table_[illegal_index];
    104     }
    105   }
    106 
    107   // Initialization should have been successful.
    108   DCHECK(IsDispatchTableInitialized());
    109 }
    110 
    111 Code* Interpreter::GetBytecodeHandler(Bytecode bytecode,
    112                                       OperandScale operand_scale) {
    113   DCHECK(IsDispatchTableInitialized());
    114   DCHECK(Bytecodes::BytecodeHasHandler(bytecode, operand_scale));
    115   size_t index = GetDispatchTableIndex(bytecode, operand_scale);
    116   Address code_entry = dispatch_table_[index];
    117   return Code::GetCodeFromTargetAddress(code_entry);
    118 }
    119 
    120 // static
    121 size_t Interpreter::GetDispatchTableIndex(Bytecode bytecode,
    122                                           OperandScale operand_scale) {
    123   static const size_t kEntriesPerOperandScale = 1u << kBitsPerByte;
    124   size_t index = static_cast<size_t>(bytecode);
    125   switch (operand_scale) {
    126     case OperandScale::kSingle:
    127       return index;
    128     case OperandScale::kDouble:
    129       return index + kEntriesPerOperandScale;
    130     case OperandScale::kQuadruple:
    131       return index + 2 * kEntriesPerOperandScale;
    132   }
    133   UNREACHABLE();
    134   return 0;
    135 }
    136 
    137 void Interpreter::IterateDispatchTable(ObjectVisitor* v) {
    138   for (int i = 0; i < kDispatchTableSize; i++) {
    139     Address code_entry = dispatch_table_[i];
    140     Object* code = code_entry == nullptr
    141                        ? nullptr
    142                        : Code::GetCodeFromTargetAddress(code_entry);
    143     Object* old_code = code;
    144     v->VisitPointer(&code);
    145     if (code != old_code) {
    146       dispatch_table_[i] = reinterpret_cast<Code*>(code)->entry();
    147     }
    148   }
    149 }
    150 
    151 // static
    152 int Interpreter::InterruptBudget() {
    153   return FLAG_interrupt_budget * kCodeSizeMultiplier;
    154 }
    155 
    156 InterpreterCompilationJob::InterpreterCompilationJob(CompilationInfo* info)
    157     : CompilationJob(info->isolate(), info, "Ignition"), generator_(info) {}
    158 
    159 InterpreterCompilationJob::Status InterpreterCompilationJob::PrepareJobImpl() {
    160   if (FLAG_print_bytecode || FLAG_print_ast) {
    161     OFStream os(stdout);
    162     std::unique_ptr<char[]> name = info()->GetDebugName();
    163     os << "[generating bytecode for function: " << info()->GetDebugName().get()
    164        << "]" << std::endl
    165        << std::flush;
    166   }
    167 
    168 #ifdef DEBUG
    169   if (info()->parse_info() && FLAG_print_ast) {
    170     OFStream os(stdout);
    171     os << "--- AST ---" << std::endl
    172        << AstPrinter(info()->isolate()).PrintProgram(info()->literal())
    173        << std::endl
    174        << std::flush;
    175   }
    176 #endif  // DEBUG
    177 
    178   return SUCCEEDED;
    179 }
    180 
    181 InterpreterCompilationJob::Status InterpreterCompilationJob::ExecuteJobImpl() {
    182   // TODO(5203): These timers aren't thread safe, move to using the CompilerJob
    183   // timers.
    184   RuntimeCallTimerScope runtimeTimer(info()->isolate(),
    185                                      &RuntimeCallStats::CompileIgnition);
    186   TimerEventScope<TimerEventCompileIgnition> timer(info()->isolate());
    187   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileIgnition");
    188 
    189   generator()->GenerateBytecode(stack_limit());
    190 
    191   if (generator()->HasStackOverflow()) {
    192     return FAILED;
    193   }
    194   return SUCCEEDED;
    195 }
    196 
    197 InterpreterCompilationJob::Status InterpreterCompilationJob::FinalizeJobImpl() {
    198   Handle<BytecodeArray> bytecodes = generator()->FinalizeBytecode(isolate());
    199   if (generator()->HasStackOverflow()) {
    200     return FAILED;
    201   }
    202 
    203   CodeGenerator::MakeCodePrologue(info(), "interpreter");
    204 
    205   if (FLAG_print_bytecode) {
    206     OFStream os(stdout);
    207     bytecodes->Print(os);
    208     os << std::flush;
    209   }
    210 
    211   info()->SetBytecodeArray(bytecodes);
    212   info()->SetCode(info()->isolate()->builtins()->InterpreterEntryTrampoline());
    213   return SUCCEEDED;
    214 }
    215 
    216 CompilationJob* Interpreter::NewCompilationJob(CompilationInfo* info) {
    217   return new InterpreterCompilationJob(info);
    218 }
    219 
    220 bool Interpreter::IsDispatchTableInitialized() {
    221   return dispatch_table_[0] != nullptr;
    222 }
    223 
    224 bool Interpreter::ShouldInitializeDispatchTable() {
    225   if (FLAG_trace_ignition || FLAG_trace_ignition_codegen ||
    226       FLAG_trace_ignition_dispatches) {
    227     // Regenerate table to add bytecode tracing operations, print the assembly
    228     // code generated by TurboFan or instrument handlers with dispatch counters.
    229     return true;
    230   }
    231   return !IsDispatchTableInitialized();
    232 }
    233 
    234 void Interpreter::TraceCodegen(Handle<Code> code) {
    235 #ifdef ENABLE_DISASSEMBLER
    236   if (FLAG_trace_ignition_codegen) {
    237     OFStream os(stdout);
    238     code->Disassemble(nullptr, os);
    239     os << std::flush;
    240   }
    241 #endif  // ENABLE_DISASSEMBLER
    242 }
    243 
    244 const char* Interpreter::LookupNameOfBytecodeHandler(Code* code) {
    245 #ifdef ENABLE_DISASSEMBLER
    246 #define RETURN_NAME(Name, ...)                                 \
    247   if (dispatch_table_[Bytecodes::ToByte(Bytecode::k##Name)] == \
    248       code->entry()) {                                         \
    249     return #Name;                                              \
    250   }
    251   BYTECODE_LIST(RETURN_NAME)
    252 #undef RETURN_NAME
    253 #endif  // ENABLE_DISASSEMBLER
    254   return nullptr;
    255 }
    256 
    257 uintptr_t Interpreter::GetDispatchCounter(Bytecode from, Bytecode to) const {
    258   int from_index = Bytecodes::ToByte(from);
    259   int to_index = Bytecodes::ToByte(to);
    260   return bytecode_dispatch_counters_table_[from_index * kNumberOfBytecodes +
    261                                            to_index];
    262 }
    263 
    264 Local<v8::Object> Interpreter::GetDispatchCountersObject() {
    265   v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(isolate_);
    266   Local<v8::Context> context = isolate->GetCurrentContext();
    267 
    268   Local<v8::Object> counters_map = v8::Object::New(isolate);
    269 
    270   // Output is a JSON-encoded object of objects.
    271   //
    272   // The keys on the top level object are source bytecodes,
    273   // and corresponding value are objects. Keys on these last are the
    274   // destinations of the dispatch and the value associated is a counter for
    275   // the correspondent source-destination dispatch chain.
    276   //
    277   // Only non-zero counters are written to file, but an entry in the top-level
    278   // object is always present, even if the value is empty because all counters
    279   // for that source are zero.
    280 
    281   for (int from_index = 0; from_index < kNumberOfBytecodes; ++from_index) {
    282     Bytecode from_bytecode = Bytecodes::FromByte(from_index);
    283     Local<v8::Object> counters_row = v8::Object::New(isolate);
    284 
    285     for (int to_index = 0; to_index < kNumberOfBytecodes; ++to_index) {
    286       Bytecode to_bytecode = Bytecodes::FromByte(to_index);
    287       uintptr_t counter = GetDispatchCounter(from_bytecode, to_bytecode);
    288 
    289       if (counter > 0) {
    290         std::string to_name = Bytecodes::ToString(to_bytecode);
    291         Local<v8::String> to_name_object =
    292             v8::String::NewFromUtf8(isolate, to_name.c_str(),
    293                                     NewStringType::kNormal)
    294                 .ToLocalChecked();
    295         Local<v8::Number> counter_object = v8::Number::New(isolate, counter);
    296         CHECK(counters_row
    297                   ->DefineOwnProperty(context, to_name_object, counter_object)
    298                   .IsJust());
    299       }
    300     }
    301 
    302     std::string from_name = Bytecodes::ToString(from_bytecode);
    303     Local<v8::String> from_name_object =
    304         v8::String::NewFromUtf8(isolate, from_name.c_str(),
    305                                 NewStringType::kNormal)
    306             .ToLocalChecked();
    307 
    308     CHECK(
    309         counters_map->DefineOwnProperty(context, from_name_object, counters_row)
    310             .IsJust());
    311   }
    312 
    313   return counters_map;
    314 }
    315 
    316 // LdaZero
    317 //
    318 // Load literal '0' into the accumulator.
    319 void Interpreter::DoLdaZero(InterpreterAssembler* assembler) {
    320   Node* zero_value = __ NumberConstant(0.0);
    321   __ SetAccumulator(zero_value);
    322   __ Dispatch();
    323 }
    324 
    325 // LdaSmi <imm>
    326 //
    327 // Load an integer literal into the accumulator as a Smi.
    328 void Interpreter::DoLdaSmi(InterpreterAssembler* assembler) {
    329   Node* raw_int = __ BytecodeOperandImm(0);
    330   Node* smi_int = __ SmiTag(raw_int);
    331   __ SetAccumulator(smi_int);
    332   __ Dispatch();
    333 }
    334 
    335 // LdaConstant <idx>
    336 //
    337 // Load constant literal at |idx| in the constant pool into the accumulator.
    338 void Interpreter::DoLdaConstant(InterpreterAssembler* assembler) {
    339   Node* index = __ BytecodeOperandIdx(0);
    340   Node* constant = __ LoadConstantPoolEntry(index);
    341   __ SetAccumulator(constant);
    342   __ Dispatch();
    343 }
    344 
    345 // LdaUndefined
    346 //
    347 // Load Undefined into the accumulator.
    348 void Interpreter::DoLdaUndefined(InterpreterAssembler* assembler) {
    349   Node* undefined_value =
    350       __ HeapConstant(isolate_->factory()->undefined_value());
    351   __ SetAccumulator(undefined_value);
    352   __ Dispatch();
    353 }
    354 
    355 // LdaNull
    356 //
    357 // Load Null into the accumulator.
    358 void Interpreter::DoLdaNull(InterpreterAssembler* assembler) {
    359   Node* null_value = __ HeapConstant(isolate_->factory()->null_value());
    360   __ SetAccumulator(null_value);
    361   __ Dispatch();
    362 }
    363 
    364 // LdaTheHole
    365 //
    366 // Load TheHole into the accumulator.
    367 void Interpreter::DoLdaTheHole(InterpreterAssembler* assembler) {
    368   Node* the_hole_value = __ HeapConstant(isolate_->factory()->the_hole_value());
    369   __ SetAccumulator(the_hole_value);
    370   __ Dispatch();
    371 }
    372 
    373 // LdaTrue
    374 //
    375 // Load True into the accumulator.
    376 void Interpreter::DoLdaTrue(InterpreterAssembler* assembler) {
    377   Node* true_value = __ HeapConstant(isolate_->factory()->true_value());
    378   __ SetAccumulator(true_value);
    379   __ Dispatch();
    380 }
    381 
    382 // LdaFalse
    383 //
    384 // Load False into the accumulator.
    385 void Interpreter::DoLdaFalse(InterpreterAssembler* assembler) {
    386   Node* false_value = __ HeapConstant(isolate_->factory()->false_value());
    387   __ SetAccumulator(false_value);
    388   __ Dispatch();
    389 }
    390 
    391 // Ldar <src>
    392 //
    393 // Load accumulator with value from register <src>.
    394 void Interpreter::DoLdar(InterpreterAssembler* assembler) {
    395   Node* reg_index = __ BytecodeOperandReg(0);
    396   Node* value = __ LoadRegister(reg_index);
    397   __ SetAccumulator(value);
    398   __ Dispatch();
    399 }
    400 
    401 // Star <dst>
    402 //
    403 // Store accumulator to register <dst>.
    404 void Interpreter::DoStar(InterpreterAssembler* assembler) {
    405   Node* reg_index = __ BytecodeOperandReg(0);
    406   Node* accumulator = __ GetAccumulator();
    407   __ StoreRegister(accumulator, reg_index);
    408   __ Dispatch();
    409 }
    410 
    411 // Mov <src> <dst>
    412 //
    413 // Stores the value of register <src> to register <dst>.
    414 void Interpreter::DoMov(InterpreterAssembler* assembler) {
    415   Node* src_index = __ BytecodeOperandReg(0);
    416   Node* src_value = __ LoadRegister(src_index);
    417   Node* dst_index = __ BytecodeOperandReg(1);
    418   __ StoreRegister(src_value, dst_index);
    419   __ Dispatch();
    420 }
    421 
    422 Node* Interpreter::BuildLoadGlobal(Callable ic, Node* context,
    423                                    Node* feedback_slot,
    424                                    InterpreterAssembler* assembler) {
    425   typedef LoadGlobalWithVectorDescriptor Descriptor;
    426 
    427   // Load the global via the LoadGlobalIC.
    428   Node* code_target = __ HeapConstant(ic.code());
    429   Node* smi_slot = __ SmiTag(feedback_slot);
    430   Node* type_feedback_vector = __ LoadTypeFeedbackVector();
    431   return __ CallStub(ic.descriptor(), code_target, context,
    432                      Arg(Descriptor::kSlot, smi_slot),
    433                      Arg(Descriptor::kVector, type_feedback_vector));
    434 }
    435 
    436 // LdaGlobal <slot>
    437 //
    438 // Load the global with name in constant pool entry <name_index> into the
    439 // accumulator using FeedBackVector slot <slot> outside of a typeof.
    440 void Interpreter::DoLdaGlobal(InterpreterAssembler* assembler) {
    441   Callable ic =
    442       CodeFactory::LoadGlobalICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF);
    443 
    444   Node* context = __ GetContext();
    445 
    446   Node* raw_slot = __ BytecodeOperandIdx(0);
    447   Node* result = BuildLoadGlobal(ic, context, raw_slot, assembler);
    448   __ SetAccumulator(result);
    449   __ Dispatch();
    450 }
    451 
    452 // LdaGlobalInsideTypeof <slot>
    453 //
    454 // Load the global with name in constant pool entry <name_index> into the
    455 // accumulator using FeedBackVector slot <slot> inside of a typeof.
    456 void Interpreter::DoLdaGlobalInsideTypeof(InterpreterAssembler* assembler) {
    457   Callable ic =
    458       CodeFactory::LoadGlobalICInOptimizedCode(isolate_, INSIDE_TYPEOF);
    459 
    460   Node* context = __ GetContext();
    461 
    462   Node* raw_slot = __ BytecodeOperandIdx(0);
    463   Node* result = BuildLoadGlobal(ic, context, raw_slot, assembler);
    464   __ SetAccumulator(result);
    465   __ Dispatch();
    466 }
    467 
    468 void Interpreter::DoStaGlobal(Callable ic, InterpreterAssembler* assembler) {
    469   typedef StoreWithVectorDescriptor Descriptor;
    470   // Get the global object.
    471   Node* context = __ GetContext();
    472   Node* native_context = __ LoadNativeContext(context);
    473   Node* global =
    474       __ LoadContextElement(native_context, Context::EXTENSION_INDEX);
    475 
    476   // Store the global via the StoreIC.
    477   Node* code_target = __ HeapConstant(ic.code());
    478   Node* constant_index = __ BytecodeOperandIdx(0);
    479   Node* name = __ LoadConstantPoolEntry(constant_index);
    480   Node* value = __ GetAccumulator();
    481   Node* raw_slot = __ BytecodeOperandIdx(1);
    482   Node* smi_slot = __ SmiTag(raw_slot);
    483   Node* type_feedback_vector = __ LoadTypeFeedbackVector();
    484   __ CallStub(ic.descriptor(), code_target, context,
    485               Arg(Descriptor::kReceiver, global), Arg(Descriptor::kName, name),
    486               Arg(Descriptor::kValue, value), Arg(Descriptor::kSlot, smi_slot),
    487               Arg(Descriptor::kVector, type_feedback_vector));
    488   __ Dispatch();
    489 }
    490 
    491 // StaGlobalSloppy <name_index> <slot>
    492 //
    493 // Store the value in the accumulator into the global with name in constant pool
    494 // entry <name_index> using FeedBackVector slot <slot> in sloppy mode.
    495 void Interpreter::DoStaGlobalSloppy(InterpreterAssembler* assembler) {
    496   Callable ic = CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY);
    497   DoStaGlobal(ic, assembler);
    498 }
    499 
    500 // StaGlobalStrict <name_index> <slot>
    501 //
    502 // Store the value in the accumulator into the global with name in constant pool
    503 // entry <name_index> using FeedBackVector slot <slot> in strict mode.
    504 void Interpreter::DoStaGlobalStrict(InterpreterAssembler* assembler) {
    505   Callable ic = CodeFactory::StoreICInOptimizedCode(isolate_, STRICT);
    506   DoStaGlobal(ic, assembler);
    507 }
    508 
    509 // LdaContextSlot <context> <slot_index> <depth>
    510 //
    511 // Load the object in |slot_index| of the context at |depth| in the context
    512 // chain starting at |context| into the accumulator.
    513 void Interpreter::DoLdaContextSlot(InterpreterAssembler* assembler) {
    514   Node* reg_index = __ BytecodeOperandReg(0);
    515   Node* context = __ LoadRegister(reg_index);
    516   Node* slot_index = __ BytecodeOperandIdx(1);
    517   Node* depth = __ BytecodeOperandUImm(2);
    518   Node* slot_context = __ GetContextAtDepth(context, depth);
    519   Node* result = __ LoadContextElement(slot_context, slot_index);
    520   __ SetAccumulator(result);
    521   __ Dispatch();
    522 }
    523 
    524 // LdaCurrentContextSlot <slot_index>
    525 //
    526 // Load the object in |slot_index| of the current context into the accumulator.
    527 void Interpreter::DoLdaCurrentContextSlot(InterpreterAssembler* assembler) {
    528   Node* slot_index = __ BytecodeOperandIdx(0);
    529   Node* slot_context = __ GetContext();
    530   Node* result = __ LoadContextElement(slot_context, slot_index);
    531   __ SetAccumulator(result);
    532   __ Dispatch();
    533 }
    534 
    535 // StaContextSlot <context> <slot_index> <depth>
    536 //
    537 // Stores the object in the accumulator into |slot_index| of the context at
    538 // |depth| in the context chain starting at |context|.
    539 void Interpreter::DoStaContextSlot(InterpreterAssembler* assembler) {
    540   Node* value = __ GetAccumulator();
    541   Node* reg_index = __ BytecodeOperandReg(0);
    542   Node* context = __ LoadRegister(reg_index);
    543   Node* slot_index = __ BytecodeOperandIdx(1);
    544   Node* depth = __ BytecodeOperandUImm(2);
    545   Node* slot_context = __ GetContextAtDepth(context, depth);
    546   __ StoreContextElement(slot_context, slot_index, value);
    547   __ Dispatch();
    548 }
    549 
    550 // StaCurrentContextSlot <slot_index>
    551 //
    552 // Stores the object in the accumulator into |slot_index| of the current
    553 // context.
    554 void Interpreter::DoStaCurrentContextSlot(InterpreterAssembler* assembler) {
    555   Node* value = __ GetAccumulator();
    556   Node* slot_index = __ BytecodeOperandIdx(0);
    557   Node* slot_context = __ GetContext();
    558   __ StoreContextElement(slot_context, slot_index, value);
    559   __ Dispatch();
    560 }
    561 
    562 void Interpreter::DoLdaLookupSlot(Runtime::FunctionId function_id,
    563                                   InterpreterAssembler* assembler) {
    564   Node* name_index = __ BytecodeOperandIdx(0);
    565   Node* name = __ LoadConstantPoolEntry(name_index);
    566   Node* context = __ GetContext();
    567   Node* result = __ CallRuntime(function_id, context, name);
    568   __ SetAccumulator(result);
    569   __ Dispatch();
    570 }
    571 
    572 // LdaLookupSlot <name_index>
    573 //
    574 // Lookup the object with the name in constant pool entry |name_index|
    575 // dynamically.
    576 void Interpreter::DoLdaLookupSlot(InterpreterAssembler* assembler) {
    577   DoLdaLookupSlot(Runtime::kLoadLookupSlot, assembler);
    578 }
    579 
    580 // LdaLookupSlotInsideTypeof <name_index>
    581 //
    582 // Lookup the object with the name in constant pool entry |name_index|
    583 // dynamically without causing a NoReferenceError.
    584 void Interpreter::DoLdaLookupSlotInsideTypeof(InterpreterAssembler* assembler) {
    585   DoLdaLookupSlot(Runtime::kLoadLookupSlotInsideTypeof, assembler);
    586 }
    587 
    588 void Interpreter::DoLdaLookupContextSlot(Runtime::FunctionId function_id,
    589                                          InterpreterAssembler* assembler) {
    590   Node* context = __ GetContext();
    591   Node* name_index = __ BytecodeOperandIdx(0);
    592   Node* slot_index = __ BytecodeOperandIdx(1);
    593   Node* depth = __ BytecodeOperandUImm(2);
    594 
    595   Label slowpath(assembler, Label::kDeferred);
    596 
    597   // Check for context extensions to allow the fast path.
    598   __ GotoIfHasContextExtensionUpToDepth(context, depth, &slowpath);
    599 
    600   // Fast path does a normal load context.
    601   {
    602     Node* slot_context = __ GetContextAtDepth(context, depth);
    603     Node* result = __ LoadContextElement(slot_context, slot_index);
    604     __ SetAccumulator(result);
    605     __ Dispatch();
    606   }
    607 
    608   // Slow path when we have to call out to the runtime.
    609   __ Bind(&slowpath);
    610   {
    611     Node* name = __ LoadConstantPoolEntry(name_index);
    612     Node* result = __ CallRuntime(function_id, context, name);
    613     __ SetAccumulator(result);
    614     __ Dispatch();
    615   }
    616 }
    617 
    618 // LdaLookupSlot <name_index>
    619 //
    620 // Lookup the object with the name in constant pool entry |name_index|
    621 // dynamically.
    622 void Interpreter::DoLdaLookupContextSlot(InterpreterAssembler* assembler) {
    623   DoLdaLookupContextSlot(Runtime::kLoadLookupSlot, assembler);
    624 }
    625 
    626 // LdaLookupSlotInsideTypeof <name_index>
    627 //
    628 // Lookup the object with the name in constant pool entry |name_index|
    629 // dynamically without causing a NoReferenceError.
    630 void Interpreter::DoLdaLookupContextSlotInsideTypeof(
    631     InterpreterAssembler* assembler) {
    632   DoLdaLookupContextSlot(Runtime::kLoadLookupSlotInsideTypeof, assembler);
    633 }
    634 
    635 void Interpreter::DoLdaLookupGlobalSlot(Runtime::FunctionId function_id,
    636                                         InterpreterAssembler* assembler) {
    637   Node* context = __ GetContext();
    638   Node* name_index = __ BytecodeOperandIdx(0);
    639   Node* feedback_slot = __ BytecodeOperandIdx(1);
    640   Node* depth = __ BytecodeOperandUImm(2);
    641 
    642   Label slowpath(assembler, Label::kDeferred);
    643 
    644   // Check for context extensions to allow the fast path
    645   __ GotoIfHasContextExtensionUpToDepth(context, depth, &slowpath);
    646 
    647   // Fast path does a normal load global
    648   {
    649     Callable ic = CodeFactory::LoadGlobalICInOptimizedCode(
    650         isolate_, function_id == Runtime::kLoadLookupSlotInsideTypeof
    651                       ? INSIDE_TYPEOF
    652                       : NOT_INSIDE_TYPEOF);
    653     Node* result = BuildLoadGlobal(ic, context, feedback_slot, assembler);
    654     __ SetAccumulator(result);
    655     __ Dispatch();
    656   }
    657 
    658   // Slow path when we have to call out to the runtime
    659   __ Bind(&slowpath);
    660   {
    661     Node* name = __ LoadConstantPoolEntry(name_index);
    662     Node* result = __ CallRuntime(function_id, context, name);
    663     __ SetAccumulator(result);
    664     __ Dispatch();
    665   }
    666 }
    667 
    668 // LdaLookupGlobalSlot <name_index> <feedback_slot> <depth>
    669 //
    670 // Lookup the object with the name in constant pool entry |name_index|
    671 // dynamically.
    672 void Interpreter::DoLdaLookupGlobalSlot(InterpreterAssembler* assembler) {
    673   DoLdaLookupGlobalSlot(Runtime::kLoadLookupSlot, assembler);
    674 }
    675 
    676 // LdaLookupGlobalSlotInsideTypeof <name_index> <feedback_slot> <depth>
    677 //
    678 // Lookup the object with the name in constant pool entry |name_index|
    679 // dynamically without causing a NoReferenceError.
    680 void Interpreter::DoLdaLookupGlobalSlotInsideTypeof(
    681     InterpreterAssembler* assembler) {
    682   DoLdaLookupGlobalSlot(Runtime::kLoadLookupSlotInsideTypeof, assembler);
    683 }
    684 
    685 void Interpreter::DoStaLookupSlot(LanguageMode language_mode,
    686                                   InterpreterAssembler* assembler) {
    687   Node* value = __ GetAccumulator();
    688   Node* index = __ BytecodeOperandIdx(0);
    689   Node* name = __ LoadConstantPoolEntry(index);
    690   Node* context = __ GetContext();
    691   Node* result = __ CallRuntime(is_strict(language_mode)
    692                                     ? Runtime::kStoreLookupSlot_Strict
    693                                     : Runtime::kStoreLookupSlot_Sloppy,
    694                                 context, name, value);
    695   __ SetAccumulator(result);
    696   __ Dispatch();
    697 }
    698 
    699 // StaLookupSlotSloppy <name_index>
    700 //
    701 // Store the object in accumulator to the object with the name in constant
    702 // pool entry |name_index| in sloppy mode.
    703 void Interpreter::DoStaLookupSlotSloppy(InterpreterAssembler* assembler) {
    704   DoStaLookupSlot(LanguageMode::SLOPPY, assembler);
    705 }
    706 
    707 // StaLookupSlotStrict <name_index>
    708 //
    709 // Store the object in accumulator to the object with the name in constant
    710 // pool entry |name_index| in strict mode.
    711 void Interpreter::DoStaLookupSlotStrict(InterpreterAssembler* assembler) {
    712   DoStaLookupSlot(LanguageMode::STRICT, assembler);
    713 }
    714 
    715 // LdaNamedProperty <object> <name_index> <slot>
    716 //
    717 // Calls the LoadIC at FeedBackVector slot <slot> for <object> and the name at
    718 // constant pool entry <name_index>.
    719 void Interpreter::DoLdaNamedProperty(InterpreterAssembler* assembler) {
    720   typedef LoadWithVectorDescriptor Descriptor;
    721   Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_);
    722   Node* code_target = __ HeapConstant(ic.code());
    723   Node* register_index = __ BytecodeOperandReg(0);
    724   Node* object = __ LoadRegister(register_index);
    725   Node* constant_index = __ BytecodeOperandIdx(1);
    726   Node* name = __ LoadConstantPoolEntry(constant_index);
    727   Node* raw_slot = __ BytecodeOperandIdx(2);
    728   Node* smi_slot = __ SmiTag(raw_slot);
    729   Node* type_feedback_vector = __ LoadTypeFeedbackVector();
    730   Node* context = __ GetContext();
    731   Node* result = __ CallStub(
    732       ic.descriptor(), code_target, context, Arg(Descriptor::kReceiver, object),
    733       Arg(Descriptor::kName, name), Arg(Descriptor::kSlot, smi_slot),
    734       Arg(Descriptor::kVector, type_feedback_vector));
    735   __ SetAccumulator(result);
    736   __ Dispatch();
    737 }
    738 
    739 // KeyedLoadIC <object> <slot>
    740 //
    741 // Calls the KeyedLoadIC at FeedBackVector slot <slot> for <object> and the key
    742 // in the accumulator.
    743 void Interpreter::DoLdaKeyedProperty(InterpreterAssembler* assembler) {
    744   typedef LoadWithVectorDescriptor Descriptor;
    745   Callable ic = CodeFactory::KeyedLoadICInOptimizedCode(isolate_);
    746   Node* code_target = __ HeapConstant(ic.code());
    747   Node* reg_index = __ BytecodeOperandReg(0);
    748   Node* object = __ LoadRegister(reg_index);
    749   Node* name = __ GetAccumulator();
    750   Node* raw_slot = __ BytecodeOperandIdx(1);
    751   Node* smi_slot = __ SmiTag(raw_slot);
    752   Node* type_feedback_vector = __ LoadTypeFeedbackVector();
    753   Node* context = __ GetContext();
    754   Node* result = __ CallStub(
    755       ic.descriptor(), code_target, context, Arg(Descriptor::kReceiver, object),
    756       Arg(Descriptor::kName, name), Arg(Descriptor::kSlot, smi_slot),
    757       Arg(Descriptor::kVector, type_feedback_vector));
    758   __ SetAccumulator(result);
    759   __ Dispatch();
    760 }
    761 
    762 void Interpreter::DoStoreIC(Callable ic, InterpreterAssembler* assembler) {
    763   typedef StoreWithVectorDescriptor Descriptor;
    764   Node* code_target = __ HeapConstant(ic.code());
    765   Node* object_reg_index = __ BytecodeOperandReg(0);
    766   Node* object = __ LoadRegister(object_reg_index);
    767   Node* constant_index = __ BytecodeOperandIdx(1);
    768   Node* name = __ LoadConstantPoolEntry(constant_index);
    769   Node* value = __ GetAccumulator();
    770   Node* raw_slot = __ BytecodeOperandIdx(2);
    771   Node* smi_slot = __ SmiTag(raw_slot);
    772   Node* type_feedback_vector = __ LoadTypeFeedbackVector();
    773   Node* context = __ GetContext();
    774   __ CallStub(ic.descriptor(), code_target, context,
    775               Arg(Descriptor::kReceiver, object), Arg(Descriptor::kName, name),
    776               Arg(Descriptor::kValue, value), Arg(Descriptor::kSlot, smi_slot),
    777               Arg(Descriptor::kVector, type_feedback_vector));
    778   __ Dispatch();
    779 }
    780 
    781 // StaNamedPropertySloppy <object> <name_index> <slot>
    782 //
    783 // Calls the sloppy mode StoreIC at FeedBackVector slot <slot> for <object> and
    784 // the name in constant pool entry <name_index> with the value in the
    785 // accumulator.
    786 void Interpreter::DoStaNamedPropertySloppy(InterpreterAssembler* assembler) {
    787   Callable ic = CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY);
    788   DoStoreIC(ic, assembler);
    789 }
    790 
    791 // StaNamedPropertyStrict <object> <name_index> <slot>
    792 //
    793 // Calls the strict mode StoreIC at FeedBackVector slot <slot> for <object> and
    794 // the name in constant pool entry <name_index> with the value in the
    795 // accumulator.
    796 void Interpreter::DoStaNamedPropertyStrict(InterpreterAssembler* assembler) {
    797   Callable ic = CodeFactory::StoreICInOptimizedCode(isolate_, STRICT);
    798   DoStoreIC(ic, assembler);
    799 }
    800 
    801 void Interpreter::DoKeyedStoreIC(Callable ic, InterpreterAssembler* assembler) {
    802   typedef StoreWithVectorDescriptor Descriptor;
    803   Node* code_target = __ HeapConstant(ic.code());
    804   Node* object_reg_index = __ BytecodeOperandReg(0);
    805   Node* object = __ LoadRegister(object_reg_index);
    806   Node* name_reg_index = __ BytecodeOperandReg(1);
    807   Node* name = __ LoadRegister(name_reg_index);
    808   Node* value = __ GetAccumulator();
    809   Node* raw_slot = __ BytecodeOperandIdx(2);
    810   Node* smi_slot = __ SmiTag(raw_slot);
    811   Node* type_feedback_vector = __ LoadTypeFeedbackVector();
    812   Node* context = __ GetContext();
    813   __ CallStub(ic.descriptor(), code_target, context,
    814               Arg(Descriptor::kReceiver, object), Arg(Descriptor::kName, name),
    815               Arg(Descriptor::kValue, value), Arg(Descriptor::kSlot, smi_slot),
    816               Arg(Descriptor::kVector, type_feedback_vector));
    817   __ Dispatch();
    818 }
    819 
    820 // StaKeyedPropertySloppy <object> <key> <slot>
    821 //
    822 // Calls the sloppy mode KeyStoreIC at FeedBackVector slot <slot> for <object>
    823 // and the key <key> with the value in the accumulator.
    824 void Interpreter::DoStaKeyedPropertySloppy(InterpreterAssembler* assembler) {
    825   Callable ic = CodeFactory::KeyedStoreICInOptimizedCode(isolate_, SLOPPY);
    826   DoKeyedStoreIC(ic, assembler);
    827 }
    828 
    829 // StaKeyedPropertyStrict <object> <key> <slot>
    830 //
    831 // Calls the strict mode KeyStoreIC at FeedBackVector slot <slot> for <object>
    832 // and the key <key> with the value in the accumulator.
    833 void Interpreter::DoStaKeyedPropertyStrict(InterpreterAssembler* assembler) {
    834   Callable ic = CodeFactory::KeyedStoreICInOptimizedCode(isolate_, STRICT);
    835   DoKeyedStoreIC(ic, assembler);
    836 }
    837 
    838 // LdaModuleVariable <cell_index> <depth>
    839 //
    840 // Load the contents of a module variable into the accumulator.  The variable is
    841 // identified by <cell_index>.  <depth> is the depth of the current context
    842 // relative to the module context.
    843 void Interpreter::DoLdaModuleVariable(InterpreterAssembler* assembler) {
    844   Node* cell_index = __ BytecodeOperandImm(0);
    845   Node* depth = __ BytecodeOperandUImm(1);
    846 
    847   Node* module_context = __ GetContextAtDepth(__ GetContext(), depth);
    848   Node* module =
    849       __ LoadContextElement(module_context, Context::EXTENSION_INDEX);
    850 
    851   Label if_export(assembler), if_import(assembler), end(assembler);
    852   __ Branch(__ IntPtrGreaterThan(cell_index, __ IntPtrConstant(0)), &if_export,
    853             &if_import);
    854 
    855   __ Bind(&if_export);
    856   {
    857     Node* regular_exports =
    858         __ LoadObjectField(module, Module::kRegularExportsOffset);
    859     // The actual array index is (cell_index - 1).
    860     Node* export_index = __ IntPtrSub(cell_index, __ IntPtrConstant(1));
    861     Node* cell = __ LoadFixedArrayElement(regular_exports, export_index);
    862     __ SetAccumulator(__ LoadObjectField(cell, Cell::kValueOffset));
    863     __ Goto(&end);
    864   }
    865 
    866   __ Bind(&if_import);
    867   {
    868     Node* regular_imports =
    869         __ LoadObjectField(module, Module::kRegularImportsOffset);
    870     // The actual array index is (-cell_index - 1).
    871     Node* import_index = __ IntPtrSub(__ IntPtrConstant(-1), cell_index);
    872     Node* cell = __ LoadFixedArrayElement(regular_imports, import_index);
    873     __ SetAccumulator(__ LoadObjectField(cell, Cell::kValueOffset));
    874     __ Goto(&end);
    875   }
    876 
    877   __ Bind(&end);
    878   __ Dispatch();
    879 }
    880 
    881 // StaModuleVariable <cell_index> <depth>
    882 //
    883 // Store accumulator to the module variable identified by <cell_index>.
    884 // <depth> is the depth of the current context relative to the module context.
    885 void Interpreter::DoStaModuleVariable(InterpreterAssembler* assembler) {
    886   Node* value = __ GetAccumulator();
    887   Node* cell_index = __ BytecodeOperandImm(0);
    888   Node* depth = __ BytecodeOperandUImm(1);
    889 
    890   Node* module_context = __ GetContextAtDepth(__ GetContext(), depth);
    891   Node* module =
    892       __ LoadContextElement(module_context, Context::EXTENSION_INDEX);
    893 
    894   Label if_export(assembler), if_import(assembler), end(assembler);
    895   __ Branch(__ IntPtrGreaterThan(cell_index, __ IntPtrConstant(0)), &if_export,
    896             &if_import);
    897 
    898   __ Bind(&if_export);
    899   {
    900     Node* regular_exports =
    901         __ LoadObjectField(module, Module::kRegularExportsOffset);
    902     // The actual array index is (cell_index - 1).
    903     Node* export_index = __ IntPtrSub(cell_index, __ IntPtrConstant(1));
    904     Node* cell = __ LoadFixedArrayElement(regular_exports, export_index);
    905     __ StoreObjectField(cell, Cell::kValueOffset, value);
    906     __ Goto(&end);
    907   }
    908 
    909   __ Bind(&if_import);
    910   {
    911     // Not supported (probably never).
    912     __ Abort(kUnsupportedModuleOperation);
    913     __ Goto(&end);
    914   }
    915 
    916   __ Bind(&end);
    917   __ Dispatch();
    918 }
    919 
    920 // PushContext <context>
    921 //
    922 // Saves the current context in <context>, and pushes the accumulator as the
    923 // new current context.
    924 void Interpreter::DoPushContext(InterpreterAssembler* assembler) {
    925   Node* reg_index = __ BytecodeOperandReg(0);
    926   Node* new_context = __ GetAccumulator();
    927   Node* old_context = __ GetContext();
    928   __ StoreRegister(old_context, reg_index);
    929   __ SetContext(new_context);
    930   __ Dispatch();
    931 }
    932 
    933 // PopContext <context>
    934 //
    935 // Pops the current context and sets <context> as the new context.
    936 void Interpreter::DoPopContext(InterpreterAssembler* assembler) {
    937   Node* reg_index = __ BytecodeOperandReg(0);
    938   Node* context = __ LoadRegister(reg_index);
    939   __ SetContext(context);
    940   __ Dispatch();
    941 }
    942 
    943 // TODO(mythria): Remove this function once all CompareOps record type feedback.
    944 void Interpreter::DoCompareOp(Token::Value compare_op,
    945                               InterpreterAssembler* assembler) {
    946   Node* reg_index = __ BytecodeOperandReg(0);
    947   Node* lhs = __ LoadRegister(reg_index);
    948   Node* rhs = __ GetAccumulator();
    949   Node* context = __ GetContext();
    950   Node* result;
    951   switch (compare_op) {
    952     case Token::IN:
    953       result = assembler->HasProperty(rhs, lhs, context);
    954       break;
    955     case Token::INSTANCEOF:
    956       result = assembler->InstanceOf(lhs, rhs, context);
    957       break;
    958     default:
    959       UNREACHABLE();
    960   }
    961   __ SetAccumulator(result);
    962   __ Dispatch();
    963 }
    964 
    965 template <class Generator>
    966 void Interpreter::DoBinaryOpWithFeedback(InterpreterAssembler* assembler) {
    967   Node* reg_index = __ BytecodeOperandReg(0);
    968   Node* lhs = __ LoadRegister(reg_index);
    969   Node* rhs = __ GetAccumulator();
    970   Node* context = __ GetContext();
    971   Node* slot_index = __ BytecodeOperandIdx(1);
    972   Node* type_feedback_vector = __ LoadTypeFeedbackVector();
    973   Node* result = Generator::Generate(assembler, lhs, rhs, slot_index,
    974                                      type_feedback_vector, context);
    975   __ SetAccumulator(result);
    976   __ Dispatch();
    977 }
    978 
    979 void Interpreter::DoCompareOpWithFeedback(Token::Value compare_op,
    980                                           InterpreterAssembler* assembler) {
    981   Node* reg_index = __ BytecodeOperandReg(0);
    982   Node* lhs = __ LoadRegister(reg_index);
    983   Node* rhs = __ GetAccumulator();
    984   Node* context = __ GetContext();
    985   Node* slot_index = __ BytecodeOperandIdx(1);
    986   Node* type_feedback_vector = __ LoadTypeFeedbackVector();
    987 
    988   // TODO(interpreter): the only reason this check is here is because we
    989   // sometimes emit comparisons that shouldn't collect feedback (e.g.
    990   // try-finally blocks and generators), and we could get rid of this by
    991   // introducing Smi equality tests.
    992   Label skip_feedback_update(assembler);
    993   __ GotoIf(__ WordEqual(slot_index, __ IntPtrConstant(0)),
    994             &skip_feedback_update);
    995 
    996   Variable var_type_feedback(assembler, MachineRepresentation::kWord32);
    997   Label lhs_is_smi(assembler), lhs_is_not_smi(assembler),
    998       gather_rhs_type(assembler), do_compare(assembler);
    999   __ Branch(__ TaggedIsSmi(lhs), &lhs_is_smi, &lhs_is_not_smi);
   1000 
   1001   __ Bind(&lhs_is_smi);
   1002   var_type_feedback.Bind(
   1003       __ Int32Constant(CompareOperationFeedback::kSignedSmall));
   1004   __ Goto(&gather_rhs_type);
   1005 
   1006   __ Bind(&lhs_is_not_smi);
   1007   {
   1008     Label lhs_is_number(assembler), lhs_is_not_number(assembler);
   1009     Node* lhs_map = __ LoadMap(lhs);
   1010     __ Branch(__ WordEqual(lhs_map, __ HeapNumberMapConstant()), &lhs_is_number,
   1011               &lhs_is_not_number);
   1012 
   1013     __ Bind(&lhs_is_number);
   1014     var_type_feedback.Bind(__ Int32Constant(CompareOperationFeedback::kNumber));
   1015     __ Goto(&gather_rhs_type);
   1016 
   1017     __ Bind(&lhs_is_not_number);
   1018     var_type_feedback.Bind(__ Int32Constant(CompareOperationFeedback::kAny));
   1019     __ Goto(&do_compare);
   1020   }
   1021 
   1022   __ Bind(&gather_rhs_type);
   1023   {
   1024     Label rhs_is_smi(assembler);
   1025     __ GotoIf(__ TaggedIsSmi(rhs), &rhs_is_smi);
   1026 
   1027     Node* rhs_map = __ LoadMap(rhs);
   1028     Node* rhs_type =
   1029         __ Select(__ WordEqual(rhs_map, __ HeapNumberMapConstant()),
   1030                   __ Int32Constant(CompareOperationFeedback::kNumber),
   1031                   __ Int32Constant(CompareOperationFeedback::kAny));
   1032     var_type_feedback.Bind(__ Word32Or(var_type_feedback.value(), rhs_type));
   1033     __ Goto(&do_compare);
   1034 
   1035     __ Bind(&rhs_is_smi);
   1036     var_type_feedback.Bind(
   1037         __ Word32Or(var_type_feedback.value(),
   1038                     __ Int32Constant(CompareOperationFeedback::kSignedSmall)));
   1039     __ Goto(&do_compare);
   1040   }
   1041 
   1042   __ Bind(&do_compare);
   1043   __ UpdateFeedback(var_type_feedback.value(), type_feedback_vector,
   1044                     slot_index);
   1045   __ Goto(&skip_feedback_update);
   1046 
   1047   __ Bind(&skip_feedback_update);
   1048   Node* result;
   1049   switch (compare_op) {
   1050     case Token::EQ:
   1051       result = assembler->Equal(CodeStubAssembler::kDontNegateResult, lhs, rhs,
   1052                                 context);
   1053       break;
   1054     case Token::NE:
   1055       result =
   1056           assembler->Equal(CodeStubAssembler::kNegateResult, lhs, rhs, context);
   1057       break;
   1058     case Token::EQ_STRICT:
   1059       result = assembler->StrictEqual(CodeStubAssembler::kDontNegateResult, lhs,
   1060                                       rhs, context);
   1061       break;
   1062     case Token::LT:
   1063       result = assembler->RelationalComparison(CodeStubAssembler::kLessThan,
   1064                                                lhs, rhs, context);
   1065       break;
   1066     case Token::GT:
   1067       result = assembler->RelationalComparison(CodeStubAssembler::kGreaterThan,
   1068                                                lhs, rhs, context);
   1069       break;
   1070     case Token::LTE:
   1071       result = assembler->RelationalComparison(
   1072           CodeStubAssembler::kLessThanOrEqual, lhs, rhs, context);
   1073       break;
   1074     case Token::GTE:
   1075       result = assembler->RelationalComparison(
   1076           CodeStubAssembler::kGreaterThanOrEqual, lhs, rhs, context);
   1077       break;
   1078     default:
   1079       UNREACHABLE();
   1080   }
   1081   __ SetAccumulator(result);
   1082   __ Dispatch();
   1083 }
   1084 
   1085 // Add <src>
   1086 //
   1087 // Add register <src> to accumulator.
   1088 void Interpreter::DoAdd(InterpreterAssembler* assembler) {
   1089   DoBinaryOpWithFeedback<AddWithFeedbackStub>(assembler);
   1090 }
   1091 
   1092 // Sub <src>
   1093 //
   1094 // Subtract register <src> from accumulator.
   1095 void Interpreter::DoSub(InterpreterAssembler* assembler) {
   1096   DoBinaryOpWithFeedback<SubtractWithFeedbackStub>(assembler);
   1097 }
   1098 
   1099 // Mul <src>
   1100 //
   1101 // Multiply accumulator by register <src>.
   1102 void Interpreter::DoMul(InterpreterAssembler* assembler) {
   1103   DoBinaryOpWithFeedback<MultiplyWithFeedbackStub>(assembler);
   1104 }
   1105 
   1106 // Div <src>
   1107 //
   1108 // Divide register <src> by accumulator.
   1109 void Interpreter::DoDiv(InterpreterAssembler* assembler) {
   1110   DoBinaryOpWithFeedback<DivideWithFeedbackStub>(assembler);
   1111 }
   1112 
   1113 // Mod <src>
   1114 //
   1115 // Modulo register <src> by accumulator.
   1116 void Interpreter::DoMod(InterpreterAssembler* assembler) {
   1117   DoBinaryOpWithFeedback<ModulusWithFeedbackStub>(assembler);
   1118 }
   1119 
   1120 void Interpreter::DoBitwiseBinaryOp(Token::Value bitwise_op,
   1121                                     InterpreterAssembler* assembler) {
   1122   Node* reg_index = __ BytecodeOperandReg(0);
   1123   Node* lhs = __ LoadRegister(reg_index);
   1124   Node* rhs = __ GetAccumulator();
   1125   Node* context = __ GetContext();
   1126   Node* slot_index = __ BytecodeOperandIdx(1);
   1127   Node* type_feedback_vector = __ LoadTypeFeedbackVector();
   1128 
   1129   Variable var_lhs_type_feedback(assembler, MachineRepresentation::kWord32),
   1130       var_rhs_type_feedback(assembler, MachineRepresentation::kWord32);
   1131   Node* lhs_value = __ TruncateTaggedToWord32WithFeedback(
   1132       context, lhs, &var_lhs_type_feedback);
   1133   Node* rhs_value = __ TruncateTaggedToWord32WithFeedback(
   1134       context, rhs, &var_rhs_type_feedback);
   1135   Node* result = nullptr;
   1136 
   1137   switch (bitwise_op) {
   1138     case Token::BIT_OR: {
   1139       Node* value = __ Word32Or(lhs_value, rhs_value);
   1140       result = __ ChangeInt32ToTagged(value);
   1141     } break;
   1142     case Token::BIT_AND: {
   1143       Node* value = __ Word32And(lhs_value, rhs_value);
   1144       result = __ ChangeInt32ToTagged(value);
   1145     } break;
   1146     case Token::BIT_XOR: {
   1147       Node* value = __ Word32Xor(lhs_value, rhs_value);
   1148       result = __ ChangeInt32ToTagged(value);
   1149     } break;
   1150     case Token::SHL: {
   1151       Node* value = __ Word32Shl(
   1152           lhs_value, __ Word32And(rhs_value, __ Int32Constant(0x1f)));
   1153       result = __ ChangeInt32ToTagged(value);
   1154     } break;
   1155     case Token::SHR: {
   1156       Node* value = __ Word32Shr(
   1157           lhs_value, __ Word32And(rhs_value, __ Int32Constant(0x1f)));
   1158       result = __ ChangeUint32ToTagged(value);
   1159     } break;
   1160     case Token::SAR: {
   1161       Node* value = __ Word32Sar(
   1162           lhs_value, __ Word32And(rhs_value, __ Int32Constant(0x1f)));
   1163       result = __ ChangeInt32ToTagged(value);
   1164     } break;
   1165     default:
   1166       UNREACHABLE();
   1167   }
   1168 
   1169   Node* result_type =
   1170       __ Select(__ TaggedIsSmi(result),
   1171                 __ Int32Constant(BinaryOperationFeedback::kSignedSmall),
   1172                 __ Int32Constant(BinaryOperationFeedback::kNumber));
   1173 
   1174   if (FLAG_debug_code) {
   1175     Label ok(assembler);
   1176     __ GotoIf(__ TaggedIsSmi(result), &ok);
   1177     Node* result_map = __ LoadMap(result);
   1178     __ AbortIfWordNotEqual(result_map, __ HeapNumberMapConstant(),
   1179                            kExpectedHeapNumber);
   1180     __ Goto(&ok);
   1181     __ Bind(&ok);
   1182   }
   1183 
   1184   Node* input_feedback =
   1185       __ Word32Or(var_lhs_type_feedback.value(), var_rhs_type_feedback.value());
   1186   __ UpdateFeedback(__ Word32Or(result_type, input_feedback),
   1187                     type_feedback_vector, slot_index);
   1188   __ SetAccumulator(result);
   1189   __ Dispatch();
   1190 }
   1191 
   1192 // BitwiseOr <src>
   1193 //
   1194 // BitwiseOr register <src> to accumulator.
   1195 void Interpreter::DoBitwiseOr(InterpreterAssembler* assembler) {
   1196   DoBitwiseBinaryOp(Token::BIT_OR, assembler);
   1197 }
   1198 
   1199 // BitwiseXor <src>
   1200 //
   1201 // BitwiseXor register <src> to accumulator.
   1202 void Interpreter::DoBitwiseXor(InterpreterAssembler* assembler) {
   1203   DoBitwiseBinaryOp(Token::BIT_XOR, assembler);
   1204 }
   1205 
   1206 // BitwiseAnd <src>
   1207 //
   1208 // BitwiseAnd register <src> to accumulator.
   1209 void Interpreter::DoBitwiseAnd(InterpreterAssembler* assembler) {
   1210   DoBitwiseBinaryOp(Token::BIT_AND, assembler);
   1211 }
   1212 
   1213 // ShiftLeft <src>
   1214 //
   1215 // Left shifts register <src> by the count specified in the accumulator.
   1216 // Register <src> is converted to an int32 and the accumulator to uint32
   1217 // before the operation. 5 lsb bits from the accumulator are used as count
   1218 // i.e. <src> << (accumulator & 0x1F).
   1219 void Interpreter::DoShiftLeft(InterpreterAssembler* assembler) {
   1220   DoBitwiseBinaryOp(Token::SHL, assembler);
   1221 }
   1222 
   1223 // ShiftRight <src>
   1224 //
   1225 // Right shifts register <src> by the count specified in the accumulator.
   1226 // Result is sign extended. Register <src> is converted to an int32 and the
   1227 // accumulator to uint32 before the operation. 5 lsb bits from the accumulator
   1228 // are used as count i.e. <src> >> (accumulator & 0x1F).
   1229 void Interpreter::DoShiftRight(InterpreterAssembler* assembler) {
   1230   DoBitwiseBinaryOp(Token::SAR, assembler);
   1231 }
   1232 
   1233 // ShiftRightLogical <src>
   1234 //
   1235 // Right Shifts register <src> by the count specified in the accumulator.
   1236 // Result is zero-filled. The accumulator and register <src> are converted to
   1237 // uint32 before the operation 5 lsb bits from the accumulator are used as
   1238 // count i.e. <src> << (accumulator & 0x1F).
   1239 void Interpreter::DoShiftRightLogical(InterpreterAssembler* assembler) {
   1240   DoBitwiseBinaryOp(Token::SHR, assembler);
   1241 }
   1242 
   1243 // AddSmi <imm> <reg>
   1244 //
   1245 // Adds an immediate value <imm> to register <reg>. For this
   1246 // operation <reg> is the lhs operand and <imm> is the <rhs> operand.
   1247 void Interpreter::DoAddSmi(InterpreterAssembler* assembler) {
   1248   Variable var_result(assembler, MachineRepresentation::kTagged);
   1249   Label fastpath(assembler), slowpath(assembler, Label::kDeferred),
   1250       end(assembler);
   1251 
   1252   Node* reg_index = __ BytecodeOperandReg(1);
   1253   Node* left = __ LoadRegister(reg_index);
   1254   Node* raw_int = __ BytecodeOperandImm(0);
   1255   Node* right = __ SmiTag(raw_int);
   1256   Node* slot_index = __ BytecodeOperandIdx(2);
   1257   Node* type_feedback_vector = __ LoadTypeFeedbackVector();
   1258 
   1259   // {right} is known to be a Smi.
   1260   // Check if the {left} is a Smi take the fast path.
   1261   __ Branch(__ TaggedIsSmi(left), &fastpath, &slowpath);
   1262   __ Bind(&fastpath);
   1263   {
   1264     // Try fast Smi addition first.
   1265     Node* pair = __ IntPtrAddWithOverflow(__ BitcastTaggedToWord(left),
   1266                                           __ BitcastTaggedToWord(right));
   1267     Node* overflow = __ Projection(1, pair);
   1268 
   1269     // Check if the Smi additon overflowed.
   1270     Label if_notoverflow(assembler);
   1271     __ Branch(overflow, &slowpath, &if_notoverflow);
   1272     __ Bind(&if_notoverflow);
   1273     {
   1274       __ UpdateFeedback(__ Int32Constant(BinaryOperationFeedback::kSignedSmall),
   1275                         type_feedback_vector, slot_index);
   1276       var_result.Bind(__ BitcastWordToTaggedSigned(__ Projection(0, pair)));
   1277       __ Goto(&end);
   1278     }
   1279   }
   1280   __ Bind(&slowpath);
   1281   {
   1282     Node* context = __ GetContext();
   1283     AddWithFeedbackStub stub(__ isolate());
   1284     Callable callable =
   1285         Callable(stub.GetCode(), AddWithFeedbackStub::Descriptor(__ isolate()));
   1286     Node* args[] = {left, right, slot_index, type_feedback_vector, context};
   1287     var_result.Bind(__ CallStubN(callable, args, 1));
   1288     __ Goto(&end);
   1289   }
   1290   __ Bind(&end);
   1291   {
   1292     __ SetAccumulator(var_result.value());
   1293     __ Dispatch();
   1294   }
   1295 }
   1296 
   1297 // SubSmi <imm> <reg>
   1298 //
   1299 // Subtracts an immediate value <imm> to register <reg>. For this
   1300 // operation <reg> is the lhs operand and <imm> is the rhs operand.
   1301 void Interpreter::DoSubSmi(InterpreterAssembler* assembler) {
   1302   Variable var_result(assembler, MachineRepresentation::kTagged);
   1303   Label fastpath(assembler), slowpath(assembler, Label::kDeferred),
   1304       end(assembler);
   1305 
   1306   Node* reg_index = __ BytecodeOperandReg(1);
   1307   Node* left = __ LoadRegister(reg_index);
   1308   Node* raw_int = __ BytecodeOperandImm(0);
   1309   Node* right = __ SmiTag(raw_int);
   1310   Node* slot_index = __ BytecodeOperandIdx(2);
   1311   Node* type_feedback_vector = __ LoadTypeFeedbackVector();
   1312 
   1313   // {right} is known to be a Smi.
   1314   // Check if the {left} is a Smi take the fast path.
   1315   __ Branch(__ TaggedIsSmi(left), &fastpath, &slowpath);
   1316   __ Bind(&fastpath);
   1317   {
   1318     // Try fast Smi subtraction first.
   1319     Node* pair = __ IntPtrSubWithOverflow(__ BitcastTaggedToWord(left),
   1320                                           __ BitcastTaggedToWord(right));
   1321     Node* overflow = __ Projection(1, pair);
   1322 
   1323     // Check if the Smi subtraction overflowed.
   1324     Label if_notoverflow(assembler);
   1325     __ Branch(overflow, &slowpath, &if_notoverflow);
   1326     __ Bind(&if_notoverflow);
   1327     {
   1328       __ UpdateFeedback(__ Int32Constant(BinaryOperationFeedback::kSignedSmall),
   1329                         type_feedback_vector, slot_index);
   1330       var_result.Bind(__ BitcastWordToTaggedSigned(__ Projection(0, pair)));
   1331       __ Goto(&end);
   1332     }
   1333   }
   1334   __ Bind(&slowpath);
   1335   {
   1336     Node* context = __ GetContext();
   1337     SubtractWithFeedbackStub stub(__ isolate());
   1338     Callable callable = Callable(
   1339         stub.GetCode(), SubtractWithFeedbackStub::Descriptor(__ isolate()));
   1340     Node* args[] = {left, right, slot_index, type_feedback_vector, context};
   1341     var_result.Bind(__ CallStubN(callable, args, 1));
   1342     __ Goto(&end);
   1343   }
   1344   __ Bind(&end);
   1345   {
   1346     __ SetAccumulator(var_result.value());
   1347     __ Dispatch();
   1348   }
   1349 }
   1350 
   1351 // BitwiseOr <imm> <reg>
   1352 //
   1353 // BitwiseOr <reg> with <imm>. For this operation <reg> is the lhs
   1354 // operand and <imm> is the rhs operand.
   1355 void Interpreter::DoBitwiseOrSmi(InterpreterAssembler* assembler) {
   1356   Node* reg_index = __ BytecodeOperandReg(1);
   1357   Node* left = __ LoadRegister(reg_index);
   1358   Node* raw_int = __ BytecodeOperandImm(0);
   1359   Node* right = __ SmiTag(raw_int);
   1360   Node* context = __ GetContext();
   1361   Node* slot_index = __ BytecodeOperandIdx(2);
   1362   Node* type_feedback_vector = __ LoadTypeFeedbackVector();
   1363   Variable var_lhs_type_feedback(assembler, MachineRepresentation::kWord32);
   1364   Node* lhs_value = __ TruncateTaggedToWord32WithFeedback(
   1365       context, left, &var_lhs_type_feedback);
   1366   Node* rhs_value = __ SmiToWord32(right);
   1367   Node* value = __ Word32Or(lhs_value, rhs_value);
   1368   Node* result = __ ChangeInt32ToTagged(value);
   1369   Node* result_type =
   1370       __ Select(__ TaggedIsSmi(result),
   1371                 __ Int32Constant(BinaryOperationFeedback::kSignedSmall),
   1372                 __ Int32Constant(BinaryOperationFeedback::kNumber));
   1373   __ UpdateFeedback(__ Word32Or(result_type, var_lhs_type_feedback.value()),
   1374                     type_feedback_vector, slot_index);
   1375   __ SetAccumulator(result);
   1376   __ Dispatch();
   1377 }
   1378 
   1379 // BitwiseAnd <imm> <reg>
   1380 //
   1381 // BitwiseAnd <reg> with <imm>. For this operation <reg> is the lhs
   1382 // operand and <imm> is the rhs operand.
   1383 void Interpreter::DoBitwiseAndSmi(InterpreterAssembler* assembler) {
   1384   Node* reg_index = __ BytecodeOperandReg(1);
   1385   Node* left = __ LoadRegister(reg_index);
   1386   Node* raw_int = __ BytecodeOperandImm(0);
   1387   Node* right = __ SmiTag(raw_int);
   1388   Node* context = __ GetContext();
   1389   Node* slot_index = __ BytecodeOperandIdx(2);
   1390   Node* type_feedback_vector = __ LoadTypeFeedbackVector();
   1391   Variable var_lhs_type_feedback(assembler, MachineRepresentation::kWord32);
   1392   Node* lhs_value = __ TruncateTaggedToWord32WithFeedback(
   1393       context, left, &var_lhs_type_feedback);
   1394   Node* rhs_value = __ SmiToWord32(right);
   1395   Node* value = __ Word32And(lhs_value, rhs_value);
   1396   Node* result = __ ChangeInt32ToTagged(value);
   1397   Node* result_type =
   1398       __ Select(__ TaggedIsSmi(result),
   1399                 __ Int32Constant(BinaryOperationFeedback::kSignedSmall),
   1400                 __ Int32Constant(BinaryOperationFeedback::kNumber));
   1401   __ UpdateFeedback(__ Word32Or(result_type, var_lhs_type_feedback.value()),
   1402                     type_feedback_vector, slot_index);
   1403   __ SetAccumulator(result);
   1404   __ Dispatch();
   1405 }
   1406 
   1407 // ShiftLeftSmi <imm> <reg>
   1408 //
   1409 // Left shifts register <src> by the count specified in <imm>.
   1410 // Register <src> is converted to an int32 before the operation. The 5
   1411 // lsb bits from <imm> are used as count i.e. <src> << (<imm> & 0x1F).
   1412 void Interpreter::DoShiftLeftSmi(InterpreterAssembler* assembler) {
   1413   Node* reg_index = __ BytecodeOperandReg(1);
   1414   Node* left = __ LoadRegister(reg_index);
   1415   Node* raw_int = __ BytecodeOperandImm(0);
   1416   Node* right = __ SmiTag(raw_int);
   1417   Node* context = __ GetContext();
   1418   Node* slot_index = __ BytecodeOperandIdx(2);
   1419   Node* type_feedback_vector = __ LoadTypeFeedbackVector();
   1420   Variable var_lhs_type_feedback(assembler, MachineRepresentation::kWord32);
   1421   Node* lhs_value = __ TruncateTaggedToWord32WithFeedback(
   1422       context, left, &var_lhs_type_feedback);
   1423   Node* rhs_value = __ SmiToWord32(right);
   1424   Node* shift_count = __ Word32And(rhs_value, __ Int32Constant(0x1f));
   1425   Node* value = __ Word32Shl(lhs_value, shift_count);
   1426   Node* result = __ ChangeInt32ToTagged(value);
   1427   Node* result_type =
   1428       __ Select(__ TaggedIsSmi(result),
   1429                 __ Int32Constant(BinaryOperationFeedback::kSignedSmall),
   1430                 __ Int32Constant(BinaryOperationFeedback::kNumber));
   1431   __ UpdateFeedback(__ Word32Or(result_type, var_lhs_type_feedback.value()),
   1432                     type_feedback_vector, slot_index);
   1433   __ SetAccumulator(result);
   1434   __ Dispatch();
   1435 }
   1436 
   1437 // ShiftRightSmi <imm> <reg>
   1438 //
   1439 // Right shifts register <src> by the count specified in <imm>.
   1440 // Register <src> is converted to an int32 before the operation. The 5
   1441 // lsb bits from <imm> are used as count i.e. <src> << (<imm> & 0x1F).
   1442 void Interpreter::DoShiftRightSmi(InterpreterAssembler* assembler) {
   1443   Node* reg_index = __ BytecodeOperandReg(1);
   1444   Node* left = __ LoadRegister(reg_index);
   1445   Node* raw_int = __ BytecodeOperandImm(0);
   1446   Node* right = __ SmiTag(raw_int);
   1447   Node* context = __ GetContext();
   1448   Node* slot_index = __ BytecodeOperandIdx(2);
   1449   Node* type_feedback_vector = __ LoadTypeFeedbackVector();
   1450   Variable var_lhs_type_feedback(assembler, MachineRepresentation::kWord32);
   1451   Node* lhs_value = __ TruncateTaggedToWord32WithFeedback(
   1452       context, left, &var_lhs_type_feedback);
   1453   Node* rhs_value = __ SmiToWord32(right);
   1454   Node* shift_count = __ Word32And(rhs_value, __ Int32Constant(0x1f));
   1455   Node* value = __ Word32Sar(lhs_value, shift_count);
   1456   Node* result = __ ChangeInt32ToTagged(value);
   1457   Node* result_type =
   1458       __ Select(__ TaggedIsSmi(result),
   1459                 __ Int32Constant(BinaryOperationFeedback::kSignedSmall),
   1460                 __ Int32Constant(BinaryOperationFeedback::kNumber));
   1461   __ UpdateFeedback(__ Word32Or(result_type, var_lhs_type_feedback.value()),
   1462                     type_feedback_vector, slot_index);
   1463   __ SetAccumulator(result);
   1464   __ Dispatch();
   1465 }
   1466 
   1467 Node* Interpreter::BuildUnaryOp(Callable callable,
   1468                                 InterpreterAssembler* assembler) {
   1469   Node* target = __ HeapConstant(callable.code());
   1470   Node* accumulator = __ GetAccumulator();
   1471   Node* context = __ GetContext();
   1472   return __ CallStub(callable.descriptor(), target, context, accumulator);
   1473 }
   1474 
   1475 template <class Generator>
   1476 void Interpreter::DoUnaryOpWithFeedback(InterpreterAssembler* assembler) {
   1477   Node* value = __ GetAccumulator();
   1478   Node* context = __ GetContext();
   1479   Node* slot_index = __ BytecodeOperandIdx(0);
   1480   Node* type_feedback_vector = __ LoadTypeFeedbackVector();
   1481   Node* result = Generator::Generate(assembler, value, context,
   1482                                      type_feedback_vector, slot_index);
   1483   __ SetAccumulator(result);
   1484   __ Dispatch();
   1485 }
   1486 
   1487 // ToName
   1488 //
   1489 // Convert the object referenced by the accumulator to a name.
   1490 void Interpreter::DoToName(InterpreterAssembler* assembler) {
   1491   Node* object = __ GetAccumulator();
   1492   Node* context = __ GetContext();
   1493   Node* result = __ ToName(context, object);
   1494   __ StoreRegister(result, __ BytecodeOperandReg(0));
   1495   __ Dispatch();
   1496 }
   1497 
   1498 // ToNumber
   1499 //
   1500 // Convert the object referenced by the accumulator to a number.
   1501 void Interpreter::DoToNumber(InterpreterAssembler* assembler) {
   1502   Node* object = __ GetAccumulator();
   1503   Node* context = __ GetContext();
   1504   Node* result = __ ToNumber(context, object);
   1505   __ StoreRegister(result, __ BytecodeOperandReg(0));
   1506   __ Dispatch();
   1507 }
   1508 
   1509 // ToObject
   1510 //
   1511 // Convert the object referenced by the accumulator to a JSReceiver.
   1512 void Interpreter::DoToObject(InterpreterAssembler* assembler) {
   1513   Node* result = BuildUnaryOp(CodeFactory::ToObject(isolate_), assembler);
   1514   __ StoreRegister(result, __ BytecodeOperandReg(0));
   1515   __ Dispatch();
   1516 }
   1517 
   1518 // Inc
   1519 //
   1520 // Increments value in the accumulator by one.
   1521 void Interpreter::DoInc(InterpreterAssembler* assembler) {
   1522   DoUnaryOpWithFeedback<IncStub>(assembler);
   1523 }
   1524 
   1525 // Dec
   1526 //
   1527 // Decrements value in the accumulator by one.
   1528 void Interpreter::DoDec(InterpreterAssembler* assembler) {
   1529   DoUnaryOpWithFeedback<DecStub>(assembler);
   1530 }
   1531 
   1532 // LogicalNot
   1533 //
   1534 // Perform logical-not on the accumulator, first casting the
   1535 // accumulator to a boolean value if required.
   1536 // ToBooleanLogicalNot
   1537 void Interpreter::DoToBooleanLogicalNot(InterpreterAssembler* assembler) {
   1538   Node* value = __ GetAccumulator();
   1539   Variable result(assembler, MachineRepresentation::kTagged);
   1540   Label if_true(assembler), if_false(assembler), end(assembler);
   1541   Node* true_value = __ BooleanConstant(true);
   1542   Node* false_value = __ BooleanConstant(false);
   1543   __ BranchIfToBooleanIsTrue(value, &if_true, &if_false);
   1544   __ Bind(&if_true);
   1545   {
   1546     result.Bind(false_value);
   1547     __ Goto(&end);
   1548   }
   1549   __ Bind(&if_false);
   1550   {
   1551     result.Bind(true_value);
   1552     __ Goto(&end);
   1553   }
   1554   __ Bind(&end);
   1555   __ SetAccumulator(result.value());
   1556   __ Dispatch();
   1557 }
   1558 
   1559 // LogicalNot
   1560 //
   1561 // Perform logical-not on the accumulator, which must already be a boolean
   1562 // value.
   1563 void Interpreter::DoLogicalNot(InterpreterAssembler* assembler) {
   1564   Node* value = __ GetAccumulator();
   1565   Variable result(assembler, MachineRepresentation::kTagged);
   1566   Label if_true(assembler), if_false(assembler), end(assembler);
   1567   Node* true_value = __ BooleanConstant(true);
   1568   Node* false_value = __ BooleanConstant(false);
   1569   __ Branch(__ WordEqual(value, true_value), &if_true, &if_false);
   1570   __ Bind(&if_true);
   1571   {
   1572     result.Bind(false_value);
   1573     __ Goto(&end);
   1574   }
   1575   __ Bind(&if_false);
   1576   {
   1577     if (FLAG_debug_code) {
   1578       __ AbortIfWordNotEqual(value, false_value,
   1579                              BailoutReason::kExpectedBooleanValue);
   1580     }
   1581     result.Bind(true_value);
   1582     __ Goto(&end);
   1583   }
   1584   __ Bind(&end);
   1585   __ SetAccumulator(result.value());
   1586   __ Dispatch();
   1587 }
   1588 
   1589 // TypeOf
   1590 //
   1591 // Load the accumulator with the string representating type of the
   1592 // object in the accumulator.
   1593 void Interpreter::DoTypeOf(InterpreterAssembler* assembler) {
   1594   Node* value = __ GetAccumulator();
   1595   Node* context = __ GetContext();
   1596   Node* result = assembler->Typeof(value, context);
   1597   __ SetAccumulator(result);
   1598   __ Dispatch();
   1599 }
   1600 
   1601 void Interpreter::DoDelete(Runtime::FunctionId function_id,
   1602                            InterpreterAssembler* assembler) {
   1603   Node* reg_index = __ BytecodeOperandReg(0);
   1604   Node* object = __ LoadRegister(reg_index);
   1605   Node* key = __ GetAccumulator();
   1606   Node* context = __ GetContext();
   1607   Node* result = __ CallRuntime(function_id, context, object, key);
   1608   __ SetAccumulator(result);
   1609   __ Dispatch();
   1610 }
   1611 
   1612 // DeletePropertyStrict
   1613 //
   1614 // Delete the property specified in the accumulator from the object
   1615 // referenced by the register operand following strict mode semantics.
   1616 void Interpreter::DoDeletePropertyStrict(InterpreterAssembler* assembler) {
   1617   DoDelete(Runtime::kDeleteProperty_Strict, assembler);
   1618 }
   1619 
   1620 // DeletePropertySloppy
   1621 //
   1622 // Delete the property specified in the accumulator from the object
   1623 // referenced by the register operand following sloppy mode semantics.
   1624 void Interpreter::DoDeletePropertySloppy(InterpreterAssembler* assembler) {
   1625   DoDelete(Runtime::kDeleteProperty_Sloppy, assembler);
   1626 }
   1627 
   1628 void Interpreter::DoJSCall(InterpreterAssembler* assembler,
   1629                            TailCallMode tail_call_mode) {
   1630   Node* function_reg = __ BytecodeOperandReg(0);
   1631   Node* function = __ LoadRegister(function_reg);
   1632   Node* receiver_reg = __ BytecodeOperandReg(1);
   1633   Node* receiver_arg = __ RegisterLocation(receiver_reg);
   1634   Node* receiver_args_count = __ BytecodeOperandCount(2);
   1635   Node* receiver_count = __ Int32Constant(1);
   1636   Node* args_count = __ Int32Sub(receiver_args_count, receiver_count);
   1637   Node* slot_id = __ BytecodeOperandIdx(3);
   1638   Node* type_feedback_vector = __ LoadTypeFeedbackVector();
   1639   Node* context = __ GetContext();
   1640   Node* result =
   1641       __ CallJSWithFeedback(function, context, receiver_arg, args_count,
   1642                             slot_id, type_feedback_vector, tail_call_mode);
   1643   __ SetAccumulator(result);
   1644   __ Dispatch();
   1645 }
   1646 
   1647 // Call <callable> <receiver> <arg_count> <feedback_slot_id>
   1648 //
   1649 // Call a JSfunction or Callable in |callable| with the |receiver| and
   1650 // |arg_count| arguments in subsequent registers. Collect type feedback
   1651 // into |feedback_slot_id|
   1652 void Interpreter::DoCall(InterpreterAssembler* assembler) {
   1653   DoJSCall(assembler, TailCallMode::kDisallow);
   1654 }
   1655 
   1656 // CallProperty <callable> <receiver> <arg_count> <feedback_slot_id>
   1657 //
   1658 // Call a JSfunction or Callable in |callable| with the |receiver| and
   1659 // |arg_count| arguments in subsequent registers. Collect type feedback into
   1660 // |feedback_slot_id|. The callable is known to be a property of the receiver.
   1661 void Interpreter::DoCallProperty(InterpreterAssembler* assembler) {
   1662   // TODO(leszeks): Look into making the interpreter use the fact that the
   1663   // receiver is non-null.
   1664   DoJSCall(assembler, TailCallMode::kDisallow);
   1665 }
   1666 
   1667 // TailCall <callable> <receiver> <arg_count> <feedback_slot_id>
   1668 //
   1669 // Tail call a JSfunction or Callable in |callable| with the |receiver| and
   1670 // |arg_count| arguments in subsequent registers. Collect type feedback
   1671 // into |feedback_slot_id|
   1672 void Interpreter::DoTailCall(InterpreterAssembler* assembler) {
   1673   DoJSCall(assembler, TailCallMode::kAllow);
   1674 }
   1675 
   1676 // CallRuntime <function_id> <first_arg> <arg_count>
   1677 //
   1678 // Call the runtime function |function_id| with the first argument in
   1679 // register |first_arg| and |arg_count| arguments in subsequent
   1680 // registers.
   1681 void Interpreter::DoCallRuntime(InterpreterAssembler* assembler) {
   1682   Node* function_id = __ BytecodeOperandRuntimeId(0);
   1683   Node* first_arg_reg = __ BytecodeOperandReg(1);
   1684   Node* first_arg = __ RegisterLocation(first_arg_reg);
   1685   Node* args_count = __ BytecodeOperandCount(2);
   1686   Node* context = __ GetContext();
   1687   Node* result = __ CallRuntimeN(function_id, context, first_arg, args_count);
   1688   __ SetAccumulator(result);
   1689   __ Dispatch();
   1690 }
   1691 
   1692 // InvokeIntrinsic <function_id> <first_arg> <arg_count>
   1693 //
   1694 // Implements the semantic equivalent of calling the runtime function
   1695 // |function_id| with the first argument in |first_arg| and |arg_count|
   1696 // arguments in subsequent registers.
   1697 void Interpreter::DoInvokeIntrinsic(InterpreterAssembler* assembler) {
   1698   Node* function_id = __ BytecodeOperandIntrinsicId(0);
   1699   Node* first_arg_reg = __ BytecodeOperandReg(1);
   1700   Node* arg_count = __ BytecodeOperandCount(2);
   1701   Node* context = __ GetContext();
   1702   IntrinsicsHelper helper(assembler);
   1703   Node* result =
   1704       helper.InvokeIntrinsic(function_id, context, first_arg_reg, arg_count);
   1705   __ SetAccumulator(result);
   1706   __ Dispatch();
   1707 }
   1708 
   1709 // CallRuntimeForPair <function_id> <first_arg> <arg_count> <first_return>
   1710 //
   1711 // Call the runtime function |function_id| which returns a pair, with the
   1712 // first argument in register |first_arg| and |arg_count| arguments in
   1713 // subsequent registers. Returns the result in <first_return> and
   1714 // <first_return + 1>
   1715 void Interpreter::DoCallRuntimeForPair(InterpreterAssembler* assembler) {
   1716   // Call the runtime function.
   1717   Node* function_id = __ BytecodeOperandRuntimeId(0);
   1718   Node* first_arg_reg = __ BytecodeOperandReg(1);
   1719   Node* first_arg = __ RegisterLocation(first_arg_reg);
   1720   Node* args_count = __ BytecodeOperandCount(2);
   1721   Node* context = __ GetContext();
   1722   Node* result_pair =
   1723       __ CallRuntimeN(function_id, context, first_arg, args_count, 2);
   1724 
   1725   // Store the results in <first_return> and <first_return + 1>
   1726   Node* first_return_reg = __ BytecodeOperandReg(3);
   1727   Node* second_return_reg = __ NextRegister(first_return_reg);
   1728   Node* result0 = __ Projection(0, result_pair);
   1729   Node* result1 = __ Projection(1, result_pair);
   1730   __ StoreRegister(result0, first_return_reg);
   1731   __ StoreRegister(result1, second_return_reg);
   1732   __ Dispatch();
   1733 }
   1734 
   1735 // CallJSRuntime <context_index> <receiver> <arg_count>
   1736 //
   1737 // Call the JS runtime function that has the |context_index| with the receiver
   1738 // in register |receiver| and |arg_count| arguments in subsequent registers.
   1739 void Interpreter::DoCallJSRuntime(InterpreterAssembler* assembler) {
   1740   Node* context_index = __ BytecodeOperandIdx(0);
   1741   Node* receiver_reg = __ BytecodeOperandReg(1);
   1742   Node* first_arg = __ RegisterLocation(receiver_reg);
   1743   Node* receiver_args_count = __ BytecodeOperandCount(2);
   1744   Node* receiver_count = __ Int32Constant(1);
   1745   Node* args_count = __ Int32Sub(receiver_args_count, receiver_count);
   1746 
   1747   // Get the function to call from the native context.
   1748   Node* context = __ GetContext();
   1749   Node* native_context = __ LoadNativeContext(context);
   1750   Node* function = __ LoadContextElement(native_context, context_index);
   1751 
   1752   // Call the function.
   1753   Node* result = __ CallJS(function, context, first_arg, args_count,
   1754                            TailCallMode::kDisallow);
   1755   __ SetAccumulator(result);
   1756   __ Dispatch();
   1757 }
   1758 
   1759 // New <constructor> <first_arg> <arg_count>
   1760 //
   1761 // Call operator new with |constructor| and the first argument in
   1762 // register |first_arg| and |arg_count| arguments in subsequent
   1763 // registers. The new.target is in the accumulator.
   1764 //
   1765 void Interpreter::DoNew(InterpreterAssembler* assembler) {
   1766   Callable ic = CodeFactory::InterpreterPushArgsAndConstruct(isolate_);
   1767   Node* new_target = __ GetAccumulator();
   1768   Node* constructor_reg = __ BytecodeOperandReg(0);
   1769   Node* constructor = __ LoadRegister(constructor_reg);
   1770   Node* first_arg_reg = __ BytecodeOperandReg(1);
   1771   Node* first_arg = __ RegisterLocation(first_arg_reg);
   1772   Node* args_count = __ BytecodeOperandCount(2);
   1773   Node* slot_id = __ BytecodeOperandIdx(3);
   1774   Node* type_feedback_vector = __ LoadTypeFeedbackVector();
   1775   Node* context = __ GetContext();
   1776   Node* result = __ CallConstruct(constructor, context, new_target, first_arg,
   1777                                   args_count, slot_id, type_feedback_vector);
   1778   __ SetAccumulator(result);
   1779   __ Dispatch();
   1780 }
   1781 
   1782 // TestEqual <src>
   1783 //
   1784 // Test if the value in the <src> register equals the accumulator.
   1785 void Interpreter::DoTestEqual(InterpreterAssembler* assembler) {
   1786   DoCompareOpWithFeedback(Token::Value::EQ, assembler);
   1787 }
   1788 
   1789 // TestNotEqual <src>
   1790 //
   1791 // Test if the value in the <src> register is not equal to the accumulator.
   1792 void Interpreter::DoTestNotEqual(InterpreterAssembler* assembler) {
   1793   DoCompareOpWithFeedback(Token::Value::NE, assembler);
   1794 }
   1795 
   1796 // TestEqualStrict <src>
   1797 //
   1798 // Test if the value in the <src> register is strictly equal to the accumulator.
   1799 void Interpreter::DoTestEqualStrict(InterpreterAssembler* assembler) {
   1800   DoCompareOpWithFeedback(Token::Value::EQ_STRICT, assembler);
   1801 }
   1802 
   1803 // TestLessThan <src>
   1804 //
   1805 // Test if the value in the <src> register is less than the accumulator.
   1806 void Interpreter::DoTestLessThan(InterpreterAssembler* assembler) {
   1807   DoCompareOpWithFeedback(Token::Value::LT, assembler);
   1808 }
   1809 
   1810 // TestGreaterThan <src>
   1811 //
   1812 // Test if the value in the <src> register is greater than the accumulator.
   1813 void Interpreter::DoTestGreaterThan(InterpreterAssembler* assembler) {
   1814   DoCompareOpWithFeedback(Token::Value::GT, assembler);
   1815 }
   1816 
   1817 // TestLessThanOrEqual <src>
   1818 //
   1819 // Test if the value in the <src> register is less than or equal to the
   1820 // accumulator.
   1821 void Interpreter::DoTestLessThanOrEqual(InterpreterAssembler* assembler) {
   1822   DoCompareOpWithFeedback(Token::Value::LTE, assembler);
   1823 }
   1824 
   1825 // TestGreaterThanOrEqual <src>
   1826 //
   1827 // Test if the value in the <src> register is greater than or equal to the
   1828 // accumulator.
   1829 void Interpreter::DoTestGreaterThanOrEqual(InterpreterAssembler* assembler) {
   1830   DoCompareOpWithFeedback(Token::Value::GTE, assembler);
   1831 }
   1832 
   1833 // TestIn <src>
   1834 //
   1835 // Test if the object referenced by the register operand is a property of the
   1836 // object referenced by the accumulator.
   1837 void Interpreter::DoTestIn(InterpreterAssembler* assembler) {
   1838   DoCompareOp(Token::IN, assembler);
   1839 }
   1840 
   1841 // TestInstanceOf <src>
   1842 //
   1843 // Test if the object referenced by the <src> register is an an instance of type
   1844 // referenced by the accumulator.
   1845 void Interpreter::DoTestInstanceOf(InterpreterAssembler* assembler) {
   1846   DoCompareOp(Token::INSTANCEOF, assembler);
   1847 }
   1848 
   1849 // Jump <imm>
   1850 //
   1851 // Jump by number of bytes represented by the immediate operand |imm|.
   1852 void Interpreter::DoJump(InterpreterAssembler* assembler) {
   1853   Node* relative_jump = __ BytecodeOperandImm(0);
   1854   __ Jump(relative_jump);
   1855 }
   1856 
   1857 // JumpConstant <idx>
   1858 //
   1859 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool.
   1860 void Interpreter::DoJumpConstant(InterpreterAssembler* assembler) {
   1861   Node* index = __ BytecodeOperandIdx(0);
   1862   Node* relative_jump = __ LoadAndUntagConstantPoolEntry(index);
   1863   __ Jump(relative_jump);
   1864 }
   1865 
   1866 // JumpIfTrue <imm>
   1867 //
   1868 // Jump by number of bytes represented by an immediate operand if the
   1869 // accumulator contains true.
   1870 void Interpreter::DoJumpIfTrue(InterpreterAssembler* assembler) {
   1871   Node* accumulator = __ GetAccumulator();
   1872   Node* relative_jump = __ BytecodeOperandImm(0);
   1873   Node* true_value = __ BooleanConstant(true);
   1874   __ JumpIfWordEqual(accumulator, true_value, relative_jump);
   1875 }
   1876 
   1877 // JumpIfTrueConstant <idx>
   1878 //
   1879 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool
   1880 // if the accumulator contains true.
   1881 void Interpreter::DoJumpIfTrueConstant(InterpreterAssembler* assembler) {
   1882   Node* accumulator = __ GetAccumulator();
   1883   Node* index = __ BytecodeOperandIdx(0);
   1884   Node* relative_jump = __ LoadAndUntagConstantPoolEntry(index);
   1885   Node* true_value = __ BooleanConstant(true);
   1886   __ JumpIfWordEqual(accumulator, true_value, relative_jump);
   1887 }
   1888 
   1889 // JumpIfFalse <imm>
   1890 //
   1891 // Jump by number of bytes represented by an immediate operand if the
   1892 // accumulator contains false.
   1893 void Interpreter::DoJumpIfFalse(InterpreterAssembler* assembler) {
   1894   Node* accumulator = __ GetAccumulator();
   1895   Node* relative_jump = __ BytecodeOperandImm(0);
   1896   Node* false_value = __ BooleanConstant(false);
   1897   __ JumpIfWordEqual(accumulator, false_value, relative_jump);
   1898 }
   1899 
   1900 // JumpIfFalseConstant <idx>
   1901 //
   1902 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool
   1903 // if the accumulator contains false.
   1904 void Interpreter::DoJumpIfFalseConstant(InterpreterAssembler* assembler) {
   1905   Node* accumulator = __ GetAccumulator();
   1906   Node* index = __ BytecodeOperandIdx(0);
   1907   Node* relative_jump = __ LoadAndUntagConstantPoolEntry(index);
   1908   Node* false_value = __ BooleanConstant(false);
   1909   __ JumpIfWordEqual(accumulator, false_value, relative_jump);
   1910 }
   1911 
   1912 // JumpIfToBooleanTrue <imm>
   1913 //
   1914 // Jump by number of bytes represented by an immediate operand if the object
   1915 // referenced by the accumulator is true when the object is cast to boolean.
   1916 void Interpreter::DoJumpIfToBooleanTrue(InterpreterAssembler* assembler) {
   1917   Node* value = __ GetAccumulator();
   1918   Node* relative_jump = __ BytecodeOperandImm(0);
   1919   Label if_true(assembler), if_false(assembler);
   1920   __ BranchIfToBooleanIsTrue(value, &if_true, &if_false);
   1921   __ Bind(&if_true);
   1922   __ Jump(relative_jump);
   1923   __ Bind(&if_false);
   1924   __ Dispatch();
   1925 }
   1926 
   1927 // JumpIfToBooleanTrueConstant <idx>
   1928 //
   1929 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool
   1930 // if the object referenced by the accumulator is true when the object is cast
   1931 // to boolean.
   1932 void Interpreter::DoJumpIfToBooleanTrueConstant(
   1933     InterpreterAssembler* assembler) {
   1934   Node* value = __ GetAccumulator();
   1935   Node* index = __ BytecodeOperandIdx(0);
   1936   Node* relative_jump = __ LoadAndUntagConstantPoolEntry(index);
   1937   Label if_true(assembler), if_false(assembler);
   1938   __ BranchIfToBooleanIsTrue(value, &if_true, &if_false);
   1939   __ Bind(&if_true);
   1940   __ Jump(relative_jump);
   1941   __ Bind(&if_false);
   1942   __ Dispatch();
   1943 }
   1944 
   1945 // JumpIfToBooleanFalse <imm>
   1946 //
   1947 // Jump by number of bytes represented by an immediate operand if the object
   1948 // referenced by the accumulator is false when the object is cast to boolean.
   1949 void Interpreter::DoJumpIfToBooleanFalse(InterpreterAssembler* assembler) {
   1950   Node* value = __ GetAccumulator();
   1951   Node* relative_jump = __ BytecodeOperandImm(0);
   1952   Label if_true(assembler), if_false(assembler);
   1953   __ BranchIfToBooleanIsTrue(value, &if_true, &if_false);
   1954   __ Bind(&if_true);
   1955   __ Dispatch();
   1956   __ Bind(&if_false);
   1957   __ Jump(relative_jump);
   1958 }
   1959 
   1960 // JumpIfToBooleanFalseConstant <idx>
   1961 //
   1962 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool
   1963 // if the object referenced by the accumulator is false when the object is cast
   1964 // to boolean.
   1965 void Interpreter::DoJumpIfToBooleanFalseConstant(
   1966     InterpreterAssembler* assembler) {
   1967   Node* value = __ GetAccumulator();
   1968   Node* index = __ BytecodeOperandIdx(0);
   1969   Node* relative_jump = __ LoadAndUntagConstantPoolEntry(index);
   1970   Label if_true(assembler), if_false(assembler);
   1971   __ BranchIfToBooleanIsTrue(value, &if_true, &if_false);
   1972   __ Bind(&if_true);
   1973   __ Dispatch();
   1974   __ Bind(&if_false);
   1975   __ Jump(relative_jump);
   1976 }
   1977 
   1978 // JumpIfNull <imm>
   1979 //
   1980 // Jump by number of bytes represented by an immediate operand if the object
   1981 // referenced by the accumulator is the null constant.
   1982 void Interpreter::DoJumpIfNull(InterpreterAssembler* assembler) {
   1983   Node* accumulator = __ GetAccumulator();
   1984   Node* null_value = __ HeapConstant(isolate_->factory()->null_value());
   1985   Node* relative_jump = __ BytecodeOperandImm(0);
   1986   __ JumpIfWordEqual(accumulator, null_value, relative_jump);
   1987 }
   1988 
   1989 // JumpIfNullConstant <idx>
   1990 //
   1991 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool
   1992 // if the object referenced by the accumulator is the null constant.
   1993 void Interpreter::DoJumpIfNullConstant(InterpreterAssembler* assembler) {
   1994   Node* accumulator = __ GetAccumulator();
   1995   Node* null_value = __ HeapConstant(isolate_->factory()->null_value());
   1996   Node* index = __ BytecodeOperandIdx(0);
   1997   Node* relative_jump = __ LoadAndUntagConstantPoolEntry(index);
   1998   __ JumpIfWordEqual(accumulator, null_value, relative_jump);
   1999 }
   2000 
   2001 // JumpIfUndefined <imm>
   2002 //
   2003 // Jump by number of bytes represented by an immediate operand if the object
   2004 // referenced by the accumulator is the undefined constant.
   2005 void Interpreter::DoJumpIfUndefined(InterpreterAssembler* assembler) {
   2006   Node* accumulator = __ GetAccumulator();
   2007   Node* undefined_value =
   2008       __ HeapConstant(isolate_->factory()->undefined_value());
   2009   Node* relative_jump = __ BytecodeOperandImm(0);
   2010   __ JumpIfWordEqual(accumulator, undefined_value, relative_jump);
   2011 }
   2012 
   2013 // JumpIfUndefinedConstant <idx>
   2014 //
   2015 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool
   2016 // if the object referenced by the accumulator is the undefined constant.
   2017 void Interpreter::DoJumpIfUndefinedConstant(InterpreterAssembler* assembler) {
   2018   Node* accumulator = __ GetAccumulator();
   2019   Node* undefined_value =
   2020       __ HeapConstant(isolate_->factory()->undefined_value());
   2021   Node* index = __ BytecodeOperandIdx(0);
   2022   Node* relative_jump = __ LoadAndUntagConstantPoolEntry(index);
   2023   __ JumpIfWordEqual(accumulator, undefined_value, relative_jump);
   2024 }
   2025 
   2026 // JumpIfNotHole <imm>
   2027 //
   2028 // Jump by number of bytes represented by an immediate operand if the object
   2029 // referenced by the accumulator is the hole.
   2030 void Interpreter::DoJumpIfNotHole(InterpreterAssembler* assembler) {
   2031   Node* accumulator = __ GetAccumulator();
   2032   Node* the_hole_value = __ HeapConstant(isolate_->factory()->the_hole_value());
   2033   Node* relative_jump = __ BytecodeOperandImm(0);
   2034   __ JumpIfWordNotEqual(accumulator, the_hole_value, relative_jump);
   2035 }
   2036 
   2037 // JumpIfNotHoleConstant <idx>
   2038 //
   2039 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool
   2040 // if the object referenced by the accumulator is the hole constant.
   2041 void Interpreter::DoJumpIfNotHoleConstant(InterpreterAssembler* assembler) {
   2042   Node* accumulator = __ GetAccumulator();
   2043   Node* the_hole_value = __ HeapConstant(isolate_->factory()->the_hole_value());
   2044   Node* index = __ BytecodeOperandIdx(0);
   2045   Node* relative_jump = __ LoadAndUntagConstantPoolEntry(index);
   2046   __ JumpIfWordNotEqual(accumulator, the_hole_value, relative_jump);
   2047 }
   2048 
   2049 // JumpLoop <imm> <loop_depth>
   2050 //
   2051 // Jump by number of bytes represented by the immediate operand |imm|. Also
   2052 // performs a loop nesting check and potentially triggers OSR in case the
   2053 // current OSR level matches (or exceeds) the specified |loop_depth|.
   2054 void Interpreter::DoJumpLoop(InterpreterAssembler* assembler) {
   2055   Node* relative_jump = __ BytecodeOperandImm(0);
   2056   Node* loop_depth = __ BytecodeOperandImm(1);
   2057   Node* osr_level = __ LoadOSRNestingLevel();
   2058 
   2059   // Check if OSR points at the given {loop_depth} are armed by comparing it to
   2060   // the current {osr_level} loaded from the header of the BytecodeArray.
   2061   Label ok(assembler), osr_armed(assembler, Label::kDeferred);
   2062   Node* condition = __ Int32GreaterThanOrEqual(loop_depth, osr_level);
   2063   __ Branch(condition, &ok, &osr_armed);
   2064 
   2065   __ Bind(&ok);
   2066   __ Jump(relative_jump);
   2067 
   2068   __ Bind(&osr_armed);
   2069   {
   2070     Callable callable = CodeFactory::InterpreterOnStackReplacement(isolate_);
   2071     Node* target = __ HeapConstant(callable.code());
   2072     Node* context = __ GetContext();
   2073     __ CallStub(callable.descriptor(), target, context);
   2074     __ Jump(relative_jump);
   2075   }
   2076 }
   2077 
   2078 // CreateRegExpLiteral <pattern_idx> <literal_idx> <flags>
   2079 //
   2080 // Creates a regular expression literal for literal index <literal_idx> with
   2081 // <flags> and the pattern in <pattern_idx>.
   2082 void Interpreter::DoCreateRegExpLiteral(InterpreterAssembler* assembler) {
   2083   Node* index = __ BytecodeOperandIdx(0);
   2084   Node* pattern = __ LoadConstantPoolEntry(index);
   2085   Node* literal_index_raw = __ BytecodeOperandIdx(1);
   2086   Node* literal_index = __ SmiTag(literal_index_raw);
   2087   Node* flags_raw = __ BytecodeOperandFlag(2);
   2088   Node* flags = __ SmiTag(flags_raw);
   2089   Node* closure = __ LoadRegister(Register::function_closure());
   2090   Node* context = __ GetContext();
   2091   Node* result = FastCloneRegExpStub::Generate(
   2092       assembler, closure, literal_index, pattern, flags, context);
   2093   __ SetAccumulator(result);
   2094   __ Dispatch();
   2095 }
   2096 
   2097 // CreateArrayLiteral <element_idx> <literal_idx> <flags>
   2098 //
   2099 // Creates an array literal for literal index <literal_idx> with
   2100 // CreateArrayLiteral flags <flags> and constant elements in <element_idx>.
   2101 void Interpreter::DoCreateArrayLiteral(InterpreterAssembler* assembler) {
   2102   Node* literal_index_raw = __ BytecodeOperandIdx(1);
   2103   Node* literal_index = __ SmiTag(literal_index_raw);
   2104   Node* closure = __ LoadRegister(Register::function_closure());
   2105   Node* context = __ GetContext();
   2106   Node* bytecode_flags = __ BytecodeOperandFlag(2);
   2107 
   2108   Label fast_shallow_clone(assembler),
   2109       call_runtime(assembler, Label::kDeferred);
   2110   Node* use_fast_shallow_clone = __ Word32And(
   2111       bytecode_flags,
   2112       __ Int32Constant(CreateArrayLiteralFlags::FastShallowCloneBit::kMask));
   2113   __ Branch(use_fast_shallow_clone, &fast_shallow_clone, &call_runtime);
   2114 
   2115   __ Bind(&fast_shallow_clone);
   2116   {
   2117     DCHECK(FLAG_allocation_site_pretenuring);
   2118     Node* result = FastCloneShallowArrayStub::Generate(
   2119         assembler, closure, literal_index, context, &call_runtime,
   2120         TRACK_ALLOCATION_SITE);
   2121     __ SetAccumulator(result);
   2122     __ Dispatch();
   2123   }
   2124 
   2125   __ Bind(&call_runtime);
   2126   {
   2127     STATIC_ASSERT(CreateArrayLiteralFlags::FlagsBits::kShift == 0);
   2128     Node* flags_raw = __ Word32And(
   2129         bytecode_flags,
   2130         __ Int32Constant(CreateArrayLiteralFlags::FlagsBits::kMask));
   2131     Node* flags = __ SmiTag(flags_raw);
   2132     Node* index = __ BytecodeOperandIdx(0);
   2133     Node* constant_elements = __ LoadConstantPoolEntry(index);
   2134     Node* result =
   2135         __ CallRuntime(Runtime::kCreateArrayLiteral, context, closure,
   2136                        literal_index, constant_elements, flags);
   2137     __ SetAccumulator(result);
   2138     __ Dispatch();
   2139   }
   2140 }
   2141 
   2142 // CreateObjectLiteral <element_idx> <literal_idx> <flags>
   2143 //
   2144 // Creates an object literal for literal index <literal_idx> with
   2145 // CreateObjectLiteralFlags <flags> and constant elements in <element_idx>.
   2146 void Interpreter::DoCreateObjectLiteral(InterpreterAssembler* assembler) {
   2147   Node* literal_index_raw = __ BytecodeOperandIdx(1);
   2148   Node* literal_index = __ SmiTag(literal_index_raw);
   2149   Node* bytecode_flags = __ BytecodeOperandFlag(2);
   2150   Node* closure = __ LoadRegister(Register::function_closure());
   2151 
   2152   // Check if we can do a fast clone or have to call the runtime.
   2153   Label if_fast_clone(assembler),
   2154       if_not_fast_clone(assembler, Label::kDeferred);
   2155   Node* fast_clone_properties_count =
   2156       __ DecodeWord32<CreateObjectLiteralFlags::FastClonePropertiesCountBits>(
   2157           bytecode_flags);
   2158   __ Branch(fast_clone_properties_count, &if_fast_clone, &if_not_fast_clone);
   2159 
   2160   __ Bind(&if_fast_clone);
   2161   {
   2162     // If we can do a fast clone do the fast-path in FastCloneShallowObjectStub.
   2163     Node* result = FastCloneShallowObjectStub::GenerateFastPath(
   2164         assembler, &if_not_fast_clone, closure, literal_index,
   2165         fast_clone_properties_count);
   2166     __ StoreRegister(result, __ BytecodeOperandReg(3));
   2167     __ Dispatch();
   2168   }
   2169 
   2170   __ Bind(&if_not_fast_clone);
   2171   {
   2172     // If we can't do a fast clone, call into the runtime.
   2173     Node* index = __ BytecodeOperandIdx(0);
   2174     Node* constant_elements = __ LoadConstantPoolEntry(index);
   2175     Node* context = __ GetContext();
   2176 
   2177     STATIC_ASSERT(CreateObjectLiteralFlags::FlagsBits::kShift == 0);
   2178     Node* flags_raw = __ Word32And(
   2179         bytecode_flags,
   2180         __ Int32Constant(CreateObjectLiteralFlags::FlagsBits::kMask));
   2181     Node* flags = __ SmiTag(flags_raw);
   2182 
   2183     Node* result =
   2184         __ CallRuntime(Runtime::kCreateObjectLiteral, context, closure,
   2185                        literal_index, constant_elements, flags);
   2186     __ StoreRegister(result, __ BytecodeOperandReg(3));
   2187     // TODO(klaasb) build a single dispatch once the call is inlined
   2188     __ Dispatch();
   2189   }
   2190 }
   2191 
   2192 // CreateClosure <index> <tenured>
   2193 //
   2194 // Creates a new closure for SharedFunctionInfo at position |index| in the
   2195 // constant pool and with the PretenureFlag <tenured>.
   2196 void Interpreter::DoCreateClosure(InterpreterAssembler* assembler) {
   2197   Node* index = __ BytecodeOperandIdx(0);
   2198   Node* shared = __ LoadConstantPoolEntry(index);
   2199   Node* flags = __ BytecodeOperandFlag(1);
   2200   Node* context = __ GetContext();
   2201 
   2202   Label call_runtime(assembler, Label::kDeferred);
   2203   Node* fast_new_closure = __ Word32And(
   2204       flags, __ Int32Constant(CreateClosureFlags::FastNewClosureBit::kMask));
   2205   __ GotoUnless(fast_new_closure, &call_runtime);
   2206   __ SetAccumulator(FastNewClosureStub::Generate(assembler, shared, context));
   2207   __ Dispatch();
   2208 
   2209   __ Bind(&call_runtime);
   2210   {
   2211     STATIC_ASSERT(CreateClosureFlags::PretenuredBit::kShift == 0);
   2212     Node* tenured_raw = __ Word32And(
   2213         flags, __ Int32Constant(CreateClosureFlags::PretenuredBit::kMask));
   2214     Node* tenured = __ SmiTag(tenured_raw);
   2215     Node* result = __ CallRuntime(Runtime::kInterpreterNewClosure, context,
   2216                                   shared, tenured);
   2217     __ SetAccumulator(result);
   2218     __ Dispatch();
   2219   }
   2220 }
   2221 
   2222 // CreateBlockContext <index>
   2223 //
   2224 // Creates a new block context with the scope info constant at |index| and the
   2225 // closure in the accumulator.
   2226 void Interpreter::DoCreateBlockContext(InterpreterAssembler* assembler) {
   2227   Node* index = __ BytecodeOperandIdx(0);
   2228   Node* scope_info = __ LoadConstantPoolEntry(index);
   2229   Node* closure = __ GetAccumulator();
   2230   Node* context = __ GetContext();
   2231   __ SetAccumulator(
   2232       __ CallRuntime(Runtime::kPushBlockContext, context, scope_info, closure));
   2233   __ Dispatch();
   2234 }
   2235 
   2236 // CreateCatchContext <exception> <name_idx> <scope_info_idx>
   2237 //
   2238 // Creates a new context for a catch block with the |exception| in a register,
   2239 // the variable name at |name_idx|, the ScopeInfo at |scope_info_idx|, and the
   2240 // closure in the accumulator.
   2241 void Interpreter::DoCreateCatchContext(InterpreterAssembler* assembler) {
   2242   Node* exception_reg = __ BytecodeOperandReg(0);
   2243   Node* exception = __ LoadRegister(exception_reg);
   2244   Node* name_idx = __ BytecodeOperandIdx(1);
   2245   Node* name = __ LoadConstantPoolEntry(name_idx);
   2246   Node* scope_info_idx = __ BytecodeOperandIdx(2);
   2247   Node* scope_info = __ LoadConstantPoolEntry(scope_info_idx);
   2248   Node* closure = __ GetAccumulator();
   2249   Node* context = __ GetContext();
   2250   __ SetAccumulator(__ CallRuntime(Runtime::kPushCatchContext, context, name,
   2251                                    exception, scope_info, closure));
   2252   __ Dispatch();
   2253 }
   2254 
   2255 // CreateFunctionContext <slots>
   2256 //
   2257 // Creates a new context with number of |slots| for the function closure.
   2258 void Interpreter::DoCreateFunctionContext(InterpreterAssembler* assembler) {
   2259   Node* closure = __ LoadRegister(Register::function_closure());
   2260   Node* slots = __ BytecodeOperandUImm(0);
   2261   Node* context = __ GetContext();
   2262   __ SetAccumulator(
   2263       FastNewFunctionContextStub::Generate(assembler, closure, slots, context));
   2264   __ Dispatch();
   2265 }
   2266 
   2267 // CreateWithContext <register> <scope_info_idx>
   2268 //
   2269 // Creates a new context with the ScopeInfo at |scope_info_idx| for a
   2270 // with-statement with the object in |register| and the closure in the
   2271 // accumulator.
   2272 void Interpreter::DoCreateWithContext(InterpreterAssembler* assembler) {
   2273   Node* reg_index = __ BytecodeOperandReg(0);
   2274   Node* object = __ LoadRegister(reg_index);
   2275   Node* scope_info_idx = __ BytecodeOperandIdx(1);
   2276   Node* scope_info = __ LoadConstantPoolEntry(scope_info_idx);
   2277   Node* closure = __ GetAccumulator();
   2278   Node* context = __ GetContext();
   2279   __ SetAccumulator(__ CallRuntime(Runtime::kPushWithContext, context, object,
   2280                                    scope_info, closure));
   2281   __ Dispatch();
   2282 }
   2283 
   2284 // CreateMappedArguments
   2285 //
   2286 // Creates a new mapped arguments object.
   2287 void Interpreter::DoCreateMappedArguments(InterpreterAssembler* assembler) {
   2288   Node* closure = __ LoadRegister(Register::function_closure());
   2289   Node* context = __ GetContext();
   2290 
   2291   Label if_duplicate_parameters(assembler, Label::kDeferred);
   2292   Label if_not_duplicate_parameters(assembler);
   2293 
   2294   // Check if function has duplicate parameters.
   2295   // TODO(rmcilroy): Remove this check when FastNewSloppyArgumentsStub supports
   2296   // duplicate parameters.
   2297   Node* shared_info =
   2298       __ LoadObjectField(closure, JSFunction::kSharedFunctionInfoOffset);
   2299   Node* compiler_hints = __ LoadObjectField(
   2300       shared_info, SharedFunctionInfo::kHasDuplicateParametersByteOffset,
   2301       MachineType::Uint8());
   2302   Node* duplicate_parameters_bit = __ Int32Constant(
   2303       1 << SharedFunctionInfo::kHasDuplicateParametersBitWithinByte);
   2304   Node* compare = __ Word32And(compiler_hints, duplicate_parameters_bit);
   2305   __ Branch(compare, &if_duplicate_parameters, &if_not_duplicate_parameters);
   2306 
   2307   __ Bind(&if_not_duplicate_parameters);
   2308   {
   2309     // TODO(rmcilroy): Inline FastNewSloppyArguments when it is a TurboFan stub.
   2310     Callable callable = CodeFactory::FastNewSloppyArguments(isolate_, true);
   2311     Node* target = __ HeapConstant(callable.code());
   2312     Node* result = __ CallStub(callable.descriptor(), target, context, closure);
   2313     __ SetAccumulator(result);
   2314     __ Dispatch();
   2315   }
   2316 
   2317   __ Bind(&if_duplicate_parameters);
   2318   {
   2319     Node* result =
   2320         __ CallRuntime(Runtime::kNewSloppyArguments_Generic, context, closure);
   2321     __ SetAccumulator(result);
   2322     __ Dispatch();
   2323   }
   2324 }
   2325 
   2326 // CreateUnmappedArguments
   2327 //
   2328 // Creates a new unmapped arguments object.
   2329 void Interpreter::DoCreateUnmappedArguments(InterpreterAssembler* assembler) {
   2330   // TODO(rmcilroy): Inline FastNewStrictArguments when it is a TurboFan stub.
   2331   Callable callable = CodeFactory::FastNewStrictArguments(isolate_, true);
   2332   Node* target = __ HeapConstant(callable.code());
   2333   Node* context = __ GetContext();
   2334   Node* closure = __ LoadRegister(Register::function_closure());
   2335   Node* result = __ CallStub(callable.descriptor(), target, context, closure);
   2336   __ SetAccumulator(result);
   2337   __ Dispatch();
   2338 }
   2339 
   2340 // CreateRestParameter
   2341 //
   2342 // Creates a new rest parameter array.
   2343 void Interpreter::DoCreateRestParameter(InterpreterAssembler* assembler) {
   2344   // TODO(rmcilroy): Inline FastNewRestArguments when it is a TurboFan stub.
   2345   Callable callable = CodeFactory::FastNewRestParameter(isolate_, true);
   2346   Node* target = __ HeapConstant(callable.code());
   2347   Node* closure = __ LoadRegister(Register::function_closure());
   2348   Node* context = __ GetContext();
   2349   Node* result = __ CallStub(callable.descriptor(), target, context, closure);
   2350   __ SetAccumulator(result);
   2351   __ Dispatch();
   2352 }
   2353 
   2354 // StackCheck
   2355 //
   2356 // Performs a stack guard check.
   2357 void Interpreter::DoStackCheck(InterpreterAssembler* assembler) {
   2358   Label ok(assembler), stack_check_interrupt(assembler, Label::kDeferred);
   2359 
   2360   Node* interrupt = __ StackCheckTriggeredInterrupt();
   2361   __ Branch(interrupt, &stack_check_interrupt, &ok);
   2362 
   2363   __ Bind(&ok);
   2364   __ Dispatch();
   2365 
   2366   __ Bind(&stack_check_interrupt);
   2367   {
   2368     Node* context = __ GetContext();
   2369     __ CallRuntime(Runtime::kStackGuard, context);
   2370     __ Dispatch();
   2371   }
   2372 }
   2373 
   2374 // Throw
   2375 //
   2376 // Throws the exception in the accumulator.
   2377 void Interpreter::DoThrow(InterpreterAssembler* assembler) {
   2378   Node* exception = __ GetAccumulator();
   2379   Node* context = __ GetContext();
   2380   __ CallRuntime(Runtime::kThrow, context, exception);
   2381   // We shouldn't ever return from a throw.
   2382   __ Abort(kUnexpectedReturnFromThrow);
   2383 }
   2384 
   2385 // ReThrow
   2386 //
   2387 // Re-throws the exception in the accumulator.
   2388 void Interpreter::DoReThrow(InterpreterAssembler* assembler) {
   2389   Node* exception = __ GetAccumulator();
   2390   Node* context = __ GetContext();
   2391   __ CallRuntime(Runtime::kReThrow, context, exception);
   2392   // We shouldn't ever return from a throw.
   2393   __ Abort(kUnexpectedReturnFromThrow);
   2394 }
   2395 
   2396 // Return
   2397 //
   2398 // Return the value in the accumulator.
   2399 void Interpreter::DoReturn(InterpreterAssembler* assembler) {
   2400   __ UpdateInterruptBudgetOnReturn();
   2401   Node* accumulator = __ GetAccumulator();
   2402   __ Return(accumulator);
   2403 }
   2404 
   2405 // Debugger
   2406 //
   2407 // Call runtime to handle debugger statement.
   2408 void Interpreter::DoDebugger(InterpreterAssembler* assembler) {
   2409   Node* context = __ GetContext();
   2410   __ CallRuntime(Runtime::kHandleDebuggerStatement, context);
   2411   __ Dispatch();
   2412 }
   2413 
   2414 // DebugBreak
   2415 //
   2416 // Call runtime to handle a debug break.
   2417 #define DEBUG_BREAK(Name, ...)                                                \
   2418   void Interpreter::Do##Name(InterpreterAssembler* assembler) {               \
   2419     Node* context = __ GetContext();                                          \
   2420     Node* accumulator = __ GetAccumulator();                                  \
   2421     Node* original_handler =                                                  \
   2422         __ CallRuntime(Runtime::kDebugBreakOnBytecode, context, accumulator); \
   2423     __ DispatchToBytecodeHandler(original_handler);                           \
   2424   }
   2425 DEBUG_BREAK_BYTECODE_LIST(DEBUG_BREAK);
   2426 #undef DEBUG_BREAK
   2427 
   2428 void Interpreter::BuildForInPrepareResult(Node* output_register,
   2429                                           Node* cache_type, Node* cache_array,
   2430                                           Node* cache_length,
   2431                                           InterpreterAssembler* assembler) {
   2432   __ StoreRegister(cache_type, output_register);
   2433   output_register = __ NextRegister(output_register);
   2434   __ StoreRegister(cache_array, output_register);
   2435   output_register = __ NextRegister(output_register);
   2436   __ StoreRegister(cache_length, output_register);
   2437 }
   2438 
   2439 // ForInPrepare <receiver> <cache_info_triple>
   2440 //
   2441 // Returns state for for..in loop execution based on the object in the register
   2442 // |receiver|. The object must not be null or undefined and must have been
   2443 // converted to a receiver already.
   2444 // The result is output in registers |cache_info_triple| to
   2445 // |cache_info_triple + 2|, with the registers holding cache_type, cache_array,
   2446 // and cache_length respectively.
   2447 void Interpreter::DoForInPrepare(InterpreterAssembler* assembler) {
   2448   Node* object_reg = __ BytecodeOperandReg(0);
   2449   Node* receiver = __ LoadRegister(object_reg);
   2450   Node* context = __ GetContext();
   2451   Node* const zero_smi = __ SmiConstant(Smi::kZero);
   2452 
   2453   Label nothing_to_iterate(assembler, Label::kDeferred),
   2454       use_enum_cache(assembler), use_runtime(assembler, Label::kDeferred);
   2455 
   2456   if (FLAG_debug_code) {
   2457     Label already_receiver(assembler), abort(assembler);
   2458     Node* instance_type = __ LoadInstanceType(receiver);
   2459     __ Branch(__ IsJSReceiverInstanceType(instance_type), &already_receiver,
   2460               &abort);
   2461     __ Bind(&abort);
   2462     {
   2463       __ Abort(kExpectedJSReceiver);
   2464       // TODO(klaasb) remove this unreachable Goto once Abort ends the block
   2465       __ Goto(&already_receiver);
   2466     }
   2467     __ Bind(&already_receiver);
   2468   }
   2469 
   2470   __ CheckEnumCache(receiver, &use_enum_cache, &use_runtime);
   2471 
   2472   __ Bind(&use_enum_cache);
   2473   {
   2474     // The enum cache is valid.  Load the map of the object being
   2475     // iterated over and use the cache for the iteration.
   2476     Node* cache_type = __ LoadMap(receiver);
   2477     Node* cache_length = __ EnumLength(cache_type);
   2478     __ GotoIf(assembler->WordEqual(cache_length, zero_smi),
   2479               &nothing_to_iterate);
   2480     Node* descriptors = __ LoadMapDescriptors(cache_type);
   2481     Node* cache_offset =
   2482         __ LoadObjectField(descriptors, DescriptorArray::kEnumCacheOffset);
   2483     Node* cache_array = __ LoadObjectField(
   2484         cache_offset, DescriptorArray::kEnumCacheBridgeCacheOffset);
   2485     Node* output_register = __ BytecodeOperandReg(1);
   2486     BuildForInPrepareResult(output_register, cache_type, cache_array,
   2487                             cache_length, assembler);
   2488     __ Dispatch();
   2489   }
   2490 
   2491   __ Bind(&use_runtime);
   2492   {
   2493     Node* result_triple =
   2494         __ CallRuntime(Runtime::kForInPrepare, context, receiver);
   2495     Node* cache_type = __ Projection(0, result_triple);
   2496     Node* cache_array = __ Projection(1, result_triple);
   2497     Node* cache_length = __ Projection(2, result_triple);
   2498     Node* output_register = __ BytecodeOperandReg(1);
   2499     BuildForInPrepareResult(output_register, cache_type, cache_array,
   2500                             cache_length, assembler);
   2501     __ Dispatch();
   2502   }
   2503 
   2504   __ Bind(&nothing_to_iterate);
   2505   {
   2506     // Receiver is null or undefined or descriptors are zero length.
   2507     Node* output_register = __ BytecodeOperandReg(1);
   2508     BuildForInPrepareResult(output_register, zero_smi, zero_smi, zero_smi,
   2509                             assembler);
   2510     __ Dispatch();
   2511   }
   2512 }
   2513 
   2514 // ForInNext <receiver> <index> <cache_info_pair>
   2515 //
   2516 // Returns the next enumerable property in the the accumulator.
   2517 void Interpreter::DoForInNext(InterpreterAssembler* assembler) {
   2518   Node* receiver_reg = __ BytecodeOperandReg(0);
   2519   Node* receiver = __ LoadRegister(receiver_reg);
   2520   Node* index_reg = __ BytecodeOperandReg(1);
   2521   Node* index = __ LoadRegister(index_reg);
   2522   Node* cache_type_reg = __ BytecodeOperandReg(2);
   2523   Node* cache_type = __ LoadRegister(cache_type_reg);
   2524   Node* cache_array_reg = __ NextRegister(cache_type_reg);
   2525   Node* cache_array = __ LoadRegister(cache_array_reg);
   2526 
   2527   // Load the next key from the enumeration array.
   2528   Node* key = __ LoadFixedArrayElement(cache_array, index, 0,
   2529                                        CodeStubAssembler::SMI_PARAMETERS);
   2530 
   2531   // Check if we can use the for-in fast path potentially using the enum cache.
   2532   Label if_fast(assembler), if_slow(assembler, Label::kDeferred);
   2533   Node* receiver_map = __ LoadObjectField(receiver, HeapObject::kMapOffset);
   2534   __ Branch(__ WordEqual(receiver_map, cache_type), &if_fast, &if_slow);
   2535   __ Bind(&if_fast);
   2536   {
   2537     // Enum cache in use for {receiver}, the {key} is definitely valid.
   2538     __ SetAccumulator(key);
   2539     __ Dispatch();
   2540   }
   2541   __ Bind(&if_slow);
   2542   {
   2543     // Record the fact that we hit the for-in slow path.
   2544     Node* vector_index = __ BytecodeOperandIdx(3);
   2545     Node* type_feedback_vector = __ LoadTypeFeedbackVector();
   2546     Node* megamorphic_sentinel =
   2547         __ HeapConstant(TypeFeedbackVector::MegamorphicSentinel(isolate_));
   2548     __ StoreFixedArrayElement(type_feedback_vector, vector_index,
   2549                               megamorphic_sentinel, SKIP_WRITE_BARRIER);
   2550 
   2551     // Need to filter the {key} for the {receiver}.
   2552     Node* context = __ GetContext();
   2553     Callable callable = CodeFactory::ForInFilter(assembler->isolate());
   2554     Node* result = __ CallStub(callable, context, key, receiver);
   2555     __ SetAccumulator(result);
   2556     __ Dispatch();
   2557   }
   2558 }
   2559 
   2560 // ForInContinue <index> <cache_length>
   2561 //
   2562 // Returns false if the end of the enumerable properties has been reached.
   2563 void Interpreter::DoForInContinue(InterpreterAssembler* assembler) {
   2564   Node* index_reg = __ BytecodeOperandReg(0);
   2565   Node* index = __ LoadRegister(index_reg);
   2566   Node* cache_length_reg = __ BytecodeOperandReg(1);
   2567   Node* cache_length = __ LoadRegister(cache_length_reg);
   2568 
   2569   // Check if {index} is at {cache_length} already.
   2570   Label if_true(assembler), if_false(assembler), end(assembler);
   2571   __ Branch(__ WordEqual(index, cache_length), &if_true, &if_false);
   2572   __ Bind(&if_true);
   2573   {
   2574     __ SetAccumulator(__ BooleanConstant(false));
   2575     __ Goto(&end);
   2576   }
   2577   __ Bind(&if_false);
   2578   {
   2579     __ SetAccumulator(__ BooleanConstant(true));
   2580     __ Goto(&end);
   2581   }
   2582   __ Bind(&end);
   2583   __ Dispatch();
   2584 }
   2585 
   2586 // ForInStep <index>
   2587 //
   2588 // Increments the loop counter in register |index| and stores the result
   2589 // in the accumulator.
   2590 void Interpreter::DoForInStep(InterpreterAssembler* assembler) {
   2591   Node* index_reg = __ BytecodeOperandReg(0);
   2592   Node* index = __ LoadRegister(index_reg);
   2593   Node* one = __ SmiConstant(Smi::FromInt(1));
   2594   Node* result = __ SmiAdd(index, one);
   2595   __ SetAccumulator(result);
   2596   __ Dispatch();
   2597 }
   2598 
   2599 // Wide
   2600 //
   2601 // Prefix bytecode indicating next bytecode has wide (16-bit) operands.
   2602 void Interpreter::DoWide(InterpreterAssembler* assembler) {
   2603   __ DispatchWide(OperandScale::kDouble);
   2604 }
   2605 
   2606 // ExtraWide
   2607 //
   2608 // Prefix bytecode indicating next bytecode has extra-wide (32-bit) operands.
   2609 void Interpreter::DoExtraWide(InterpreterAssembler* assembler) {
   2610   __ DispatchWide(OperandScale::kQuadruple);
   2611 }
   2612 
   2613 // Illegal
   2614 //
   2615 // An invalid bytecode aborting execution if dispatched.
   2616 void Interpreter::DoIllegal(InterpreterAssembler* assembler) {
   2617   __ Abort(kInvalidBytecode);
   2618 }
   2619 
   2620 // Nop
   2621 //
   2622 // No operation.
   2623 void Interpreter::DoNop(InterpreterAssembler* assembler) { __ Dispatch(); }
   2624 
   2625 // SuspendGenerator <generator>
   2626 //
   2627 // Exports the register file and stores it into the generator.  Also stores the
   2628 // current context, the state given in the accumulator, and the current bytecode
   2629 // offset (for debugging purposes) into the generator.
   2630 void Interpreter::DoSuspendGenerator(InterpreterAssembler* assembler) {
   2631   Node* generator_reg = __ BytecodeOperandReg(0);
   2632   Node* generator = __ LoadRegister(generator_reg);
   2633 
   2634   Label if_stepping(assembler, Label::kDeferred), ok(assembler);
   2635   Node* step_action_address = __ ExternalConstant(
   2636       ExternalReference::debug_last_step_action_address(isolate_));
   2637   Node* step_action = __ Load(MachineType::Int8(), step_action_address);
   2638   STATIC_ASSERT(StepIn > StepNext);
   2639   STATIC_ASSERT(StepFrame > StepNext);
   2640   STATIC_ASSERT(LastStepAction == StepFrame);
   2641   Node* step_next = __ Int32Constant(StepNext);
   2642   __ Branch(__ Int32LessThanOrEqual(step_next, step_action), &if_stepping, &ok);
   2643   __ Bind(&ok);
   2644 
   2645   Node* array =
   2646       __ LoadObjectField(generator, JSGeneratorObject::kOperandStackOffset);
   2647   Node* context = __ GetContext();
   2648   Node* state = __ GetAccumulator();
   2649 
   2650   __ ExportRegisterFile(array);
   2651   __ StoreObjectField(generator, JSGeneratorObject::kContextOffset, context);
   2652   __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, state);
   2653 
   2654   Node* offset = __ SmiTag(__ BytecodeOffset());
   2655   __ StoreObjectField(generator, JSGeneratorObject::kInputOrDebugPosOffset,
   2656                       offset);
   2657 
   2658   __ Dispatch();
   2659 
   2660   __ Bind(&if_stepping);
   2661   {
   2662     Node* context = __ GetContext();
   2663     __ CallRuntime(Runtime::kDebugRecordAsyncFunction, context, generator);
   2664     __ Goto(&ok);
   2665   }
   2666 }
   2667 
   2668 // ResumeGenerator <generator>
   2669 //
   2670 // Imports the register file stored in the generator. Also loads the
   2671 // generator's state and stores it in the accumulator, before overwriting it
   2672 // with kGeneratorExecuting.
   2673 void Interpreter::DoResumeGenerator(InterpreterAssembler* assembler) {
   2674   Node* generator_reg = __ BytecodeOperandReg(0);
   2675   Node* generator = __ LoadRegister(generator_reg);
   2676 
   2677   __ ImportRegisterFile(
   2678       __ LoadObjectField(generator, JSGeneratorObject::kOperandStackOffset));
   2679 
   2680   Node* old_state =
   2681       __ LoadObjectField(generator, JSGeneratorObject::kContinuationOffset);
   2682   Node* new_state = __ Int32Constant(JSGeneratorObject::kGeneratorExecuting);
   2683   __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset,
   2684       __ SmiTag(new_state));
   2685   __ SetAccumulator(old_state);
   2686 
   2687   __ Dispatch();
   2688 }
   2689 
   2690 }  // namespace interpreter
   2691 }  // namespace internal
   2692 }  // namespace v8
   2693