Emit exception handler table in TurboFan.
authormstarzinger <mstarzinger@chromium.org>
Fri, 20 Feb 2015 16:22:41 +0000 (08:22 -0800)
committerCommit bot <commit-bot@chromium.org>
Fri, 20 Feb 2015 16:22:56 +0000 (16:22 +0000)
R=bmeurer@chromium.org

Review URL: https://codereview.chromium.org/943503003

Cr-Commit-Position: refs/heads/master@{#26783}

20 files changed:
src/compiler/arm/code-generator-arm.cc
src/compiler/arm/instruction-selector-arm.cc
src/compiler/arm64/code-generator-arm64.cc
src/compiler/arm64/instruction-selector-arm64.cc
src/compiler/code-generator.cc
src/compiler/code-generator.h
src/compiler/ia32/code-generator-ia32.cc
src/compiler/ia32/instruction-selector-ia32.cc
src/compiler/instruction-selector.cc
src/compiler/instruction-selector.h
src/compiler/linkage.h
src/compiler/mips/code-generator-mips.cc
src/compiler/mips/instruction-selector-mips.cc
src/compiler/mips64/code-generator-mips64.cc
src/compiler/mips64/instruction-selector-mips64.cc
src/compiler/ppc/code-generator-ppc.cc
src/compiler/ppc/instruction-selector-ppc.cc
src/compiler/x64/code-generator-x64.cc
src/compiler/x64/instruction-selector-x64.cc
src/objects.cc

index 1ff7ea3acc65e05cf0ca29420b308efcb93d6e23..54aebd97fa13dd0df42ef5d1ea065e432a483c6f 100644 (file)
@@ -313,7 +313,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
                Operand(Code::kHeaderSize - kHeapObjectTag));
         __ Call(ip);
       }
-      AddSafepointAndDeopt(instr);
+      RecordCallPosition(instr);
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     }
@@ -328,7 +328,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
       }
       __ ldr(ip, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
       __ Call(ip);
-      AddSafepointAndDeopt(instr);
+      RecordCallPosition(instr);
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     }
index 47511a1ebf35406c3ea2d97a804ce37d4aa62a24..e08226d5f3e44eed89f623d0882c4cf487ef24f6 100644 (file)
@@ -1018,7 +1018,7 @@ void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) {
 }
 
 
-void InstructionSelector::VisitCall(Node* node) {
+void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) {
   ArmOperandGenerator g(this);
   const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node);
 
@@ -1043,6 +1043,13 @@ void InstructionSelector::VisitCall(Node* node) {
     Emit(kArmPush, g.NoOutput(), g.UseRegister(*i));
   }
 
+  // Pass label of exception handler block.
+  CallDescriptor::Flags flags = descriptor->flags();
+  if (handler != nullptr) {
+    flags |= CallDescriptor::kHasExceptionHandler;
+    buffer.instruction_args.push_back(g.Label(handler));
+  }
+
   // Select the appropriate opcode based on the call type.
   InstructionCode opcode;
   switch (descriptor->kind()) {
@@ -1057,7 +1064,7 @@ void InstructionSelector::VisitCall(Node* node) {
       UNREACHABLE();
       return;
   }
-  opcode |= MiscField::encode(descriptor->flags());
+  opcode |= MiscField::encode(flags);
 
   // Emit the call instruction.
   InstructionOperand* first_output =
index 89c2ffb6f8fd15854f3a29e248946c1f05641c41..f4370e0135b9c994694a283965a482a3575df36a 100644 (file)
@@ -335,7 +335,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
         __ Add(target, target, Code::kHeaderSize - kHeapObjectTag);
         __ Call(target);
       }
-      AddSafepointAndDeopt(instr);
+      RecordCallPosition(instr);
       break;
     }
     case kArchCallJSFunction: {
@@ -351,7 +351,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
       }
       __ Ldr(x10, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
       __ Call(x10);
-      AddSafepointAndDeopt(instr);
+      RecordCallPosition(instr);
       break;
     }
     case kArchJmp:
index 6afd3e8c1259998e646c820fab1f2e684b9b96dd..06d8f1f7a214e129ab9fe17836e1c113b9525327 100644 (file)
@@ -1080,7 +1080,7 @@ void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) {
 }
 
 
-void InstructionSelector::VisitCall(Node* node) {
+void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) {
   Arm64OperandGenerator g(this);
   const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node);
 
@@ -1127,6 +1127,13 @@ void InstructionSelector::VisitCall(Node* node) {
     }
   }
 
+  // Pass label of exception handler block.
+  CallDescriptor::Flags flags = descriptor->flags();
+  if (handler != nullptr) {
+    flags |= CallDescriptor::kHasExceptionHandler;
+    buffer.instruction_args.push_back(g.Label(handler));
+  }
+
   // Select the appropriate opcode based on the call type.
   InstructionCode opcode;
   switch (descriptor->kind()) {
@@ -1141,7 +1148,7 @@ void InstructionSelector::VisitCall(Node* node) {
       UNREACHABLE();
       return;
   }
-  opcode |= MiscField::encode(descriptor->flags());
+  opcode |= MiscField::encode(flags);
 
   // Emit the call instruction.
   InstructionOperand* first_output =
index 1a4566d60994dbba96e72fcde285c215d5f2120e..f0dd6f8d46cf0b41c3663b8fb6441f339f20a692 100644 (file)
@@ -42,6 +42,7 @@ CodeGenerator::CodeGenerator(Frame* frame, Linkage* linkage,
       masm_(info->isolate(), NULL, 0),
       resolver_(this),
       safepoints_(code->zone()),
+      handlers_(code->zone()),
       deoptimization_states_(code->zone()),
       deoptimization_literals_(code->zone()),
       translations_(code->zone()),
@@ -131,6 +132,18 @@ Handle<Code> CodeGenerator::GenerateCode() {
   result->set_stack_slots(frame()->GetSpillSlotCount());
   result->set_safepoint_table_offset(safepoints()->GetCodeOffset());
 
+  // Emit exception handler table.
+  if (!handlers_.empty()) {
+    Handle<FixedArray> table = isolate()->factory()->NewFixedArray(
+        static_cast<int>(handlers_.size()) * 2, TENURED);
+    for (size_t i = 0; i < handlers_.size(); ++i) {
+      int table_index = static_cast<int>(i * 2);
+      table->set(table_index + 0, Smi::FromInt(handlers_[i].pc_offset));
+      table->set(table_index + 1, Smi::FromInt(handlers_[i].handler->pos()));
+    }
+    result->set_handler_table(*table);
+  }
+
   PopulateDeoptimizationData(result);
 
   // Ensure there is space for lazy deoptimization in the relocation info.
@@ -321,7 +334,7 @@ Label* CodeGenerator::AddJumpTable(Label** targets, size_t target_count) {
 }
 
 
-void CodeGenerator::AddSafepointAndDeopt(Instruction* instr) {
+void CodeGenerator::RecordCallPosition(Instruction* instr) {
   CallDescriptor::Flags flags(MiscField::decode(instr->opcode()));
 
   bool needs_frame_state = (flags & CallDescriptor::kNeedsFrameState);
@@ -330,16 +343,21 @@ void CodeGenerator::AddSafepointAndDeopt(Instruction* instr) {
       instr->pointer_map(), Safepoint::kSimple, 0,
       needs_frame_state ? Safepoint::kLazyDeopt : Safepoint::kNoLazyDeopt);
 
+  if (flags & CallDescriptor::kHasExceptionHandler) {
+    InstructionOperandConverter i(this, instr);
+    BasicBlock::RpoNumber handler_rpo =
+        i.InputRpo(static_cast<int>(instr->InputCount()) - 1);
+    handlers_.push_back({GetLabel(handler_rpo), masm()->pc_offset()});
+  }
+
   if (flags & CallDescriptor::kNeedsNopAfterCall) {
     AddNopForSmiCodeInlining();
   }
 
   if (needs_frame_state) {
     MarkLazyDeoptSite();
-    // If the frame state is present, it starts at argument 1
-    // (just after the code address).
-    InstructionOperandConverter converter(this, instr);
-    // Deoptimization info starts at argument 1
+    // If the frame state is present, it starts at argument 1 (just after the
+    // code address).
     size_t frame_state_offset = 1;
     FrameStateDescriptor* descriptor =
         GetFrameStateDescriptor(instr, frame_state_offset);
index 658394b3217ad79b00bfe632425f495dfd3f13e9..3cf2183e6152413a373dce2fb17f0460495b78ff 100644 (file)
@@ -106,8 +106,10 @@ class CodeGenerator FINAL : public GapResolver::Assembler {
   void AssembleJumpTable(Label** targets, size_t target_count);
 
   // ===========================================================================
-  // Deoptimization table construction
-  void AddSafepointAndDeopt(Instruction* instr);
+  // ================== Deoptimization table construction. =====================
+  // ===========================================================================
+
+  void RecordCallPosition(Instruction* instr);
   void PopulateDeoptimizationData(Handle<Code> code);
   int DefineDeoptimizationLiteral(Handle<Object> literal);
   FrameStateDescriptor* GetFrameStateDescriptor(Instruction* instr,
@@ -126,6 +128,7 @@ class CodeGenerator FINAL : public GapResolver::Assembler {
   void MarkLazyDeoptSite();
 
   // ===========================================================================
+
   struct DeoptimizationState : ZoneObject {
    public:
     BailoutId bailout_id() const { return bailout_id_; }
@@ -143,6 +146,11 @@ class CodeGenerator FINAL : public GapResolver::Assembler {
     int pc_offset_;
   };
 
+  struct HandlerInfo {
+    Label* handler;
+    int pc_offset;
+  };
+
   friend class OutOfLineCode;
 
   Frame* const frame_;
@@ -155,8 +163,9 @@ class CodeGenerator FINAL : public GapResolver::Assembler {
   MacroAssembler masm_;
   GapResolver resolver_;
   SafepointTableBuilder safepoints_;
+  ZoneVector<HandlerInfo> handlers_;
   ZoneDeque<DeoptimizationState*> deoptimization_states_;
-  ZoneDeque<Handle<Object> > deoptimization_literals_;
+  ZoneDeque<Handle<Object>> deoptimization_literals_;
   TranslationBuffer translations_;
   int last_lazy_deopt_pc_;
   JumpTable* jump_tables_;
index d20848918d30aad46f247217479f0e6b9e39544c..0bdbc5642a01a274c2650657e09136147051e4e3 100644 (file)
@@ -292,7 +292,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
         Register reg = i.InputRegister(0);
         __ call(Operand(reg, Code::kHeaderSize - kHeapObjectTag));
       }
-      AddSafepointAndDeopt(instr);
+      RecordCallPosition(instr);
       break;
     }
     case kArchCallJSFunction: {
@@ -304,7 +304,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
         __ Assert(equal, kWrongFunctionContext);
       }
       __ call(FieldOperand(func, JSFunction::kCodeEntryOffset));
-      AddSafepointAndDeopt(instr);
+      RecordCallPosition(instr);
       break;
     }
     case kArchJmp:
index beec701903ec4598f26fb3d093b7898b2ea27804..b20bc94b64f36d6ad735f5e93a9aa7be126c48f5 100644 (file)
@@ -718,7 +718,7 @@ void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) {
 }
 
 
-void InstructionSelector::VisitCall(Node* node) {
+void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) {
   IA32OperandGenerator g(this);
   const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node);
 
@@ -745,6 +745,13 @@ void InstructionSelector::VisitCall(Node* node) {
     Emit(kIA32Push, g.NoOutput(), value);
   }
 
+  // Pass label of exception handler block.
+  CallDescriptor::Flags flags = descriptor->flags();
+  if (handler != nullptr) {
+    flags |= CallDescriptor::kHasExceptionHandler;
+    buffer.instruction_args.push_back(g.Label(handler));
+  }
+
   // Select the appropriate opcode based on the call type.
   InstructionCode opcode;
   switch (descriptor->kind()) {
@@ -759,7 +766,7 @@ void InstructionSelector::VisitCall(Node* node) {
       UNREACHABLE();
       return;
   }
-  opcode |= MiscField::encode(descriptor->flags());
+  opcode |= MiscField::encode(flags);
 
   // Emit the call instruction.
   InstructionOperand* first_output =
index 2d0b2bd8af18c44af2b4691d306ee2ed42713045..d007fbf13d57fc00e8b20c6455bc981ad176633a 100644 (file)
@@ -505,9 +505,8 @@ void InstructionSelector::VisitControl(BasicBlock* block) {
     case BasicBlock::kCall: {
       DCHECK_EQ(IrOpcode::kCall, input->opcode());
       BasicBlock* success = block->SuccessorAt(0);
-      // TODO(mstarzinger): Record location of {exception} in {handler_table}.
-      // BasicBlock* exception = block->SuccessorAt(1);
-      return VisitCall(input), VisitGoto(success);
+      BasicBlock* exception = block->SuccessorAt(1);
+      return VisitCall(input, exception), VisitGoto(success);
     }
     case BasicBlock::kBranch: {
       DCHECK_EQ(IrOpcode::kBranch, input->opcode());
@@ -756,7 +755,7 @@ void InstructionSelector::VisitNode(Node* node) {
       return VisitConstant(node);
     }
     case IrOpcode::kCall:
-      return VisitCall(node);
+      return VisitCall(node, nullptr);
     case IrOpcode::kFrameState:
     case IrOpcode::kStateValues:
       return;
index 5c31db74e9a158dd495283fbfe3f119768850530..0776ec54fc2196db8213197a2bb361779d27a02c 100644 (file)
@@ -199,7 +199,7 @@ class InstructionSelector FINAL {
   void VisitPhi(Node* node);
   void VisitProjection(Node* node);
   void VisitConstant(Node* node);
-  void VisitCall(Node* call);
+  void VisitCall(Node* call, BasicBlock* handler);
   void VisitGoto(BasicBlock* target);
   void VisitBranch(Node* input, BasicBlock* tbranch, BasicBlock* fbranch);
   void VisitSwitch(Node* node, BasicBlock* default_branch,
index a3bdbf9d5bc84671a8441f1ca80c7a5c6c728c9f..a4b587dc4499407ec711d7896d70ed21d9b94736 100644 (file)
@@ -56,11 +56,11 @@ class CallDescriptor FINAL : public ZoneObject {
   };
 
   enum Flag {
-    // TODO(jarin) kLazyDeoptimization and kNeedsFrameState should be unified.
     kNoFlags = 0u,
     kNeedsFrameState = 1u << 0,
     kPatchableCallSite = 1u << 1,
     kNeedsNopAfterCall = 1u << 2,
+    kHasExceptionHandler = 1u << 3,
     kPatchableCallSiteWithNop = kPatchableCallSite | kNeedsNopAfterCall
   };
   typedef base::Flags<Flag> Flags;
index 58c45816636df1a0f84daf29078317833105cc95..ec98ea8aa391ca4385beb2366595decbfbfbf9cc 100644 (file)
@@ -408,7 +408,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
         __ addiu(at, i.InputRegister(0), Code::kHeaderSize - kHeapObjectTag);
         __ Call(at);
       }
-      AddSafepointAndDeopt(instr);
+      RecordCallPosition(instr);
       break;
     }
     case kArchCallJSFunction: {
@@ -422,7 +422,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
 
       __ lw(at, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
       __ Call(at);
-      AddSafepointAndDeopt(instr);
+      RecordCallPosition(instr);
       break;
     }
     case kArchJmp:
index d723453c017518329fdb440bec63d62e6468a8d2..ffe8263d88569c1e5439fbb9e8a2a4b972cffe2d 100644 (file)
@@ -449,7 +449,7 @@ void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) {
 }
 
 
-void InstructionSelector::VisitCall(Node* node) {
+void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) {
   MipsOperandGenerator g(this);
   const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node);
 
@@ -476,6 +476,13 @@ void InstructionSelector::VisitCall(Node* node) {
     slot--;
   }
 
+  // Pass label of exception handler block.
+  CallDescriptor::Flags flags = descriptor->flags();
+  if (handler != nullptr) {
+    flags |= CallDescriptor::kHasExceptionHandler;
+    buffer.instruction_args.push_back(g.Label(handler));
+  }
+
   // Select the appropriate opcode based on the call type.
   InstructionCode opcode;
   switch (descriptor->kind()) {
@@ -490,7 +497,7 @@ void InstructionSelector::VisitCall(Node* node) {
       UNREACHABLE();
       return;
   }
-  opcode |= MiscField::encode(descriptor->flags());
+  opcode |= MiscField::encode(flags);
 
   // Emit the call instruction.
   InstructionOperand* first_output =
index 60e016fa2281eed086be33ec69fbc65f9f2f1273..93d2f5d5a41a018af6cc7cf12e3f0a83872d6d56 100644 (file)
@@ -408,7 +408,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
         __ daddiu(at, i.InputRegister(0), Code::kHeaderSize - kHeapObjectTag);
         __ Call(at);
       }
-      AddSafepointAndDeopt(instr);
+      RecordCallPosition(instr);
       break;
     }
     case kArchCallJSFunction: {
@@ -422,7 +422,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
 
       __ ld(at, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
       __ Call(at);
-      AddSafepointAndDeopt(instr);
+      RecordCallPosition(instr);
       break;
     }
     case kArchJmp:
index 779f786468bfa21f46df9e1f36dc60ff6eb60456..aba81d5d9d335f7967948814d136289684d7392c 100644 (file)
@@ -629,7 +629,7 @@ void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) {
 }
 
 
-void InstructionSelector::VisitCall(Node* node) {
+void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) {
   Mips64OperandGenerator g(this);
   const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node);
 
@@ -656,6 +656,13 @@ void InstructionSelector::VisitCall(Node* node) {
     slot--;
   }
 
+  // Pass label of exception handler block.
+  CallDescriptor::Flags flags = descriptor->flags();
+  if (handler != nullptr) {
+    flags |= CallDescriptor::kHasExceptionHandler;
+    buffer.instruction_args.push_back(g.Label(handler));
+  }
+
   // Select the appropriate opcode based on the call type.
   InstructionCode opcode;
   switch (descriptor->kind()) {
@@ -670,7 +677,7 @@ void InstructionSelector::VisitCall(Node* node) {
       UNREACHABLE();
       return;
   }
-  opcode |= MiscField::encode(descriptor->flags());
+  opcode |= MiscField::encode(flags);
 
   // Emit the call instruction.
   Instruction* call_instr =
index e5a3980302e17f0fdcc2bbbf110ba465957147bd..3a40fe9d8f54387f0e8e7525001bd414765f9ff1 100644 (file)
@@ -532,7 +532,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
         __ Call(Handle<Code>::cast(i.InputHeapObject(0)),
                 RelocInfo::CODE_TARGET);
       }
-      AddSafepointAndDeopt(instr);
+      RecordCallPosition(instr);
       DCHECK_EQ(LeaveRC, i.OutputRCBit());
       break;
     }
@@ -548,7 +548,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
       }
       __ LoadP(ip, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
       __ Call(ip);
-      AddSafepointAndDeopt(instr);
+      RecordCallPosition(instr);
       DCHECK_EQ(LeaveRC, i.OutputRCBit());
       break;
     }
index 3c700cbc8dfe4e4e21aede18684ef848774e01c3..bed80ed2ce4e87dfd3e289aa53d5a6ea00f67fa3 100644 (file)
@@ -1378,7 +1378,7 @@ void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
 }
 
 
-void InstructionSelector::VisitCall(Node* node) {
+void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) {
   PPCOperandGenerator g(this);
   const CallDescriptor* descriptor = OpParameter<CallDescriptor*>(node);
 
@@ -1403,6 +1403,13 @@ void InstructionSelector::VisitCall(Node* node) {
     Emit(kPPC_Push, g.NoOutput(), g.UseRegister(*i));
   }
 
+  // Pass label of exception handler block.
+  CallDescriptor::Flags flags = descriptor->flags();
+  if (handler != nullptr) {
+    flags |= CallDescriptor::kHasExceptionHandler;
+    buffer.instruction_args.push_back(g.Label(handler));
+  }
+
   // Select the appropriate opcode based on the call type.
   InstructionCode opcode;
   switch (descriptor->kind()) {
@@ -1417,7 +1424,7 @@ void InstructionSelector::VisitCall(Node* node) {
       UNREACHABLE();
       return;
   }
-  opcode |= MiscField::encode(descriptor->flags());
+  opcode |= MiscField::encode(flags);
 
   // Emit the call instruction.
   InstructionOperand* first_output =
index 973bbd1ef06bb794d153701c380eeae63b2c4057..aae5aceefbc80627d3c8d42166cfab9b6f5dadd1 100644 (file)
@@ -526,7 +526,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
         int entry = Code::kHeaderSize - kHeapObjectTag;
         __ Call(Operand(reg, entry));
       }
-      AddSafepointAndDeopt(instr);
+      RecordCallPosition(instr);
       break;
     }
     case kArchCallJSFunction: {
@@ -538,7 +538,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
         __ Assert(equal, kWrongFunctionContext);
       }
       __ Call(FieldOperand(func, JSFunction::kCodeEntryOffset));
-      AddSafepointAndDeopt(instr);
+      RecordCallPosition(instr);
       break;
     }
     case kArchJmp:
index 0689eb9adc63c029f69af82f3426cd1a4aea6ea6..9c1985961a2a82d91a28f05549b9176d108c9aca 100644 (file)
@@ -940,7 +940,7 @@ void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) {
 }
 
 
-void InstructionSelector::VisitCall(Node* node) {
+void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) {
   X64OperandGenerator g(this);
   const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node);
 
@@ -966,6 +966,13 @@ void InstructionSelector::VisitCall(Node* node) {
     Emit(kX64Push, g.NoOutput(), value);
   }
 
+  // Pass label of exception handler block.
+  CallDescriptor::Flags flags = descriptor->flags();
+  if (handler != nullptr) {
+    flags |= CallDescriptor::kHasExceptionHandler;
+    buffer.instruction_args.push_back(g.Label(handler));
+  }
+
   // Select the appropriate opcode based on the call type.
   InstructionCode opcode;
   switch (descriptor->kind()) {
@@ -980,7 +987,7 @@ void InstructionSelector::VisitCall(Node* node) {
       UNREACHABLE();
       return;
   }
-  opcode |= MiscField::encode(descriptor->flags());
+  opcode |= MiscField::encode(flags);
 
   // Emit the call instruction.
   InstructionOperand* first_output =
index 100cbf90b3493860d8bd0c5c5b4246d8f57e495d..56c377157b93350f22adb318592c39a0bf929564 100644 (file)
@@ -11828,6 +11828,19 @@ void Code::Disassemble(const char* name, std::ostream& os) {  // NOLINT
 #endif
   }
 
+  if (handler_table()->length() > 0 && is_turbofanned()) {
+    os << "Handler Table (size = " << handler_table()->Size() << ")\n";
+    for (int i = 0; i < handler_table()->length(); i += 2) {
+      int pc_offset = Smi::cast(handler_table()->get(i))->value();
+      int handler = Smi::cast(handler_table()->get(i + 1))->value();
+      os << static_cast<const void*>(instruction_start() + pc_offset) << "  ";
+      Vector<char> buf = Vector<char>::New(20);
+      SNPrintF(buf, "%4d %4d\n", pc_offset, handler);
+      os << buf.start();
+    }
+    os << "\n";
+  }
+
   os << "RelocInfo (size = " << relocation_size() << ")\n";
   for (RelocIterator it(this); !it.done(); it.next()) {
     it.rinfo()->Print(GetIsolate(), os);