Allow arguments in safepoints with registers.
authorvitalyr@chromium.org <vitalyr@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 12 Jan 2011 14:14:14 +0000 (14:14 +0000)
committervitalyr@chromium.org <vitalyr@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 12 Jan 2011 14:14:14 +0000 (14:14 +0000)
This should enable calling runtime functions with arguments from
deferred lithium code.

Review URL: http://codereview.chromium.org/6125007

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6285 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/arm/deoptimizer-arm.cc
src/frames.cc
src/frames.h
src/ia32/deoptimizer-ia32.cc
src/objects.cc
src/objects.h
src/safepoint-table.cc
src/safepoint-table.h

index 3917d6d..8a53d1c 100644 (file)
@@ -55,8 +55,9 @@ void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
   SafepointTable table(function->code());
   for (unsigned i = 0; i < table.length(); i++) {
     unsigned pc_offset = table.GetPcOffset(i);
-    int deoptimization_index = table.GetDeoptimizationIndex(i);
-    int gap_code_size = table.GetGapCodeSize(i);
+    SafepointEntry safepoint_entry = table.GetEntry(i);
+    int deoptimization_index = safepoint_entry.deoptimization_index();
+    int gap_code_size = safepoint_entry.gap_code_size();
     // Check that we did not shoot past next safepoint.
     // TODO(srdjan): How do we guarantee that safepoint code does not
     // overlap other safepoint patching code?
index 3af7288..bdc76a9 100644 (file)
@@ -329,21 +329,20 @@ void SafeStackTraceFrameIterator::Advance() {
 
 
 Code* StackFrame::GetSafepointData(Address pc,
-                                   uint8_t** safepoint_entry,
+                                   SafepointEntry* safepoint_entry,
                                    unsigned* stack_slots) {
   PcToCodeCache::PcToCodeCacheEntry* entry = PcToCodeCache::GetCacheEntry(pc);
-  uint8_t* cached_safepoint_entry = entry->safepoint_entry;
-  if (cached_safepoint_entry == NULL) {
-    cached_safepoint_entry = entry->code->GetSafepointEntry(pc);
-    ASSERT(cached_safepoint_entry != NULL);  // No safepoint found.
-    entry->safepoint_entry = cached_safepoint_entry;
+  SafepointEntry cached_safepoint_entry = entry->safepoint_entry;
+  if (!entry->safepoint_entry.is_valid()) {
+    entry->safepoint_entry = entry->code->GetSafepointEntry(pc);
+    ASSERT(entry->safepoint_entry.is_valid());
   } else {
-    ASSERT(cached_safepoint_entry == entry->code->GetSafepointEntry(pc));
+    ASSERT(entry->safepoint_entry.Equals(entry->code->GetSafepointEntry(pc)));
   }
 
   // Fill in the results and return the code.
   Code* code = entry->code;
-  *safepoint_entry = cached_safepoint_entry;
+  *safepoint_entry = entry->safepoint_entry;
   *stack_slots = code->stack_slots();
   return code;
 }
@@ -536,7 +535,7 @@ void OptimizedFrame::Iterate(ObjectVisitor* v) const {
 
   // Compute the safepoint information.
   unsigned stack_slots = 0;
-  uint8_t* safepoint_entry = NULL;
+  SafepointEntry safepoint_entry;
   Code* code = StackFrame::GetSafepointData(
       pc(), &safepoint_entry, &stack_slots);
   unsigned slot_space = stack_slots * kPointerSize;
@@ -548,10 +547,17 @@ void OptimizedFrame::Iterate(ObjectVisitor* v) const {
   Object** parameters_limit = &Memory::Object_at(
       fp() + JavaScriptFrameConstants::kFunctionOffset - slot_space);
 
+  // Visit the parameters that may be on top of the saved registers.
+  if (safepoint_entry.argument_count() > 0) {
+    v->VisitPointers(parameters_base,
+                     parameters_base + safepoint_entry.argument_count());
+    parameters_base += safepoint_entry.argument_count();
+  }
+
   // Visit the registers that contain pointers if any.
-  if (SafepointTable::HasRegisters(safepoint_entry)) {
+  if (safepoint_entry.HasRegisters()) {
     for (int i = kNumSafepointRegisters - 1; i >=0; i--) {
-      if (SafepointTable::HasRegisterAt(safepoint_entry, i)) {
+      if (safepoint_entry.HasRegisterAt(i)) {
         int reg_stack_index = MacroAssembler::SafepointRegisterStackIndex(i);
         v->VisitPointer(parameters_base + reg_stack_index);
       }
@@ -561,7 +567,8 @@ void OptimizedFrame::Iterate(ObjectVisitor* v) const {
   }
 
   // We're done dealing with the register bits.
-  safepoint_entry += kNumSafepointRegisters >> kBitsPerByteLog2;
+  uint8_t* safepoint_bits = safepoint_entry.bits();
+  safepoint_bits += kNumSafepointRegisters >> kBitsPerByteLog2;
 
   // Visit the rest of the parameters.
   v->VisitPointers(parameters_base, parameters_limit);
@@ -570,7 +577,7 @@ void OptimizedFrame::Iterate(ObjectVisitor* v) const {
   for (unsigned index = 0; index < stack_slots; index++) {
     int byte_index = index >> kBitsPerByteLog2;
     int bit_index = index & (kBitsPerByte - 1);
-    if ((safepoint_entry[byte_index] & (1U << bit_index)) != 0) {
+    if ((safepoint_bits[byte_index] & (1U << bit_index)) != 0) {
       v->VisitPointer(parameters_limit + index);
     }
   }
@@ -778,14 +785,8 @@ DeoptimizationInputData* OptimizedFrame::GetDeoptimizationData(
   ASSERT(code != NULL);
   ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION);
 
-  SafepointTable table(code);
-  unsigned pc_offset = static_cast<unsigned>(pc() - code->instruction_start());
-  for (unsigned i = 0; i < table.length(); i++) {
-    if (table.GetPcOffset(i) == pc_offset) {
-      *deopt_index = table.GetDeoptimizationIndex(i);
-      break;
-    }
-  }
+  SafepointEntry safepoint_entry = code->GetSafepointEntry(pc());
+  *deopt_index = safepoint_entry.deoptimization_index();
   ASSERT(*deopt_index != AstNode::kNoNumber);
 
   return DeoptimizationInputData::cast(code->deoptimization_data());
@@ -1150,7 +1151,7 @@ PcToCodeCache::PcToCodeCacheEntry* PcToCodeCache::GetCacheEntry(Address pc) {
     // been set. Otherwise, we risk trying to use a cache entry before
     // the code has been computed.
     entry->code = GcSafeFindCodeForPc(pc);
-    entry->safepoint_entry = NULL;
+    entry->safepoint_entry.Reset();
     entry->pc = pc;
   }
   return entry;
index 778f9d2..5378709 100644 (file)
@@ -28,6 +28,8 @@
 #ifndef V8_FRAMES_H_
 #define V8_FRAMES_H_
 
+#include "safepoint-table.h"
+
 namespace v8 {
 namespace internal {
 
@@ -51,7 +53,7 @@ class PcToCodeCache : AllStatic {
   struct PcToCodeCacheEntry {
     Address pc;
     Code* code;
-    uint8_t* safepoint_entry;
+    SafepointEntry safepoint_entry;
   };
 
   static PcToCodeCacheEntry* cache(int index) {
@@ -208,7 +210,7 @@ class StackFrame BASE_EMBEDDED {
   // safepoint entry and the number of stack slots. The pc must be at
   // a safepoint.
   static Code* GetSafepointData(Address pc,
-                                uint8_t** safepoint_entry,
+                                SafepointEntry* safepoint_entry,
                                 unsigned* stack_slots);
 
   virtual void Iterate(ObjectVisitor* v) const = 0;
index ceba249..d1c0f2b 100644 (file)
@@ -56,8 +56,9 @@ void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
   SafepointTable table(function->code());
   for (unsigned i = 0; i < table.length(); i++) {
     unsigned pc_offset = table.GetPcOffset(i);
-    int deoptimization_index = table.GetDeoptimizationIndex(i);
-    int gap_code_size = table.GetGapCodeSize(i);
+    SafepointEntry safepoint_entry = table.GetEntry(i);
+    int deoptimization_index = safepoint_entry.deoptimization_index();
+    int gap_code_size = safepoint_entry.gap_code_size();
 #ifdef DEBUG
     // Destroy the code which is not supposed to run again.
     unsigned instructions = pc_offset - last_pc_offset;
index f3f8003..cbfb920 100644 (file)
@@ -5987,14 +5987,9 @@ int Code::SourceStatementPosition(Address pc) {
 }
 
 
-uint8_t* Code::GetSafepointEntry(Address pc) {
+SafepointEntry Code::GetSafepointEntry(Address pc) {
   SafepointTable table(this);
-  unsigned pc_offset = static_cast<unsigned>(pc - instruction_start());
-  for (unsigned i = 0; i < table.length(); i++) {
-    // TODO(kasperl): Replace the linear search with binary search.
-    if (table.GetPcOffset(i) == pc_offset) return table.GetEntry(i);
-  }
-  return NULL;
+  return table.FindEntry(pc);
 }
 
 
@@ -6265,12 +6260,15 @@ void Code::Disassemble(const char* name, FILE* out) {
       PrintF(out, "%p  %4d  ", (instruction_start() + pc_offset), pc_offset);
       table.PrintEntry(i);
       PrintF(out, " (sp -> fp)");
-      int deoptimization_index = table.GetDeoptimizationIndex(i);
-      if (deoptimization_index != Safepoint::kNoDeoptimizationIndex) {
-        PrintF(out, "  %6d", deoptimization_index);
+      SafepointEntry entry = table.GetEntry(i);
+      if (entry.deoptimization_index() != Safepoint::kNoDeoptimizationIndex) {
+        PrintF(out, "  %6d", entry.deoptimization_index());
       } else {
         PrintF(out, "  <none>");
       }
+      if (entry.argument_count() > 0) {
+        PrintF(out, " argc: %d", entry.argument_count());
+      }
       PrintF(out, "\n");
     }
     PrintF(out, "\n");
index 063555e..c136dc5 100644 (file)
@@ -3121,6 +3121,9 @@ class DeoptimizationOutputData: public FixedArray {
 };
 
 
+class SafepointEntry;
+
+
 // Code describes objects with on-the-fly generated machine code.
 class Code: public HeapObject {
  public:
@@ -3268,9 +3271,8 @@ class Code: public HeapObject {
   inline byte compare_state();
   inline void set_compare_state(byte value);
 
-  // Get the safepoint entry for the given pc. Returns NULL for
-  // non-safepoint pcs.
-  uint8_t* GetSafepointEntry(Address pc);
+  // Get the safepoint entry for the given pc.
+  SafepointEntry GetSafepointEntry(Address pc);
 
   // Mark this code object as not having a stack check table.  Assumes kind
   // is FUNCTION.
index b9468a5..39b211c 100644 (file)
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include "safepoint-table.h"
+
 #include "disasm.h"
+#include "macro-assembler.h"
 
 namespace v8 {
 namespace internal {
 
+
+bool SafepointEntry::HasRegisters() const {
+  ASSERT(is_valid());
+  ASSERT(IsAligned(kNumSafepointRegisters, kBitsPerByte));
+  const int num_reg_bytes = kNumSafepointRegisters >> kBitsPerByteLog2;
+  for (int i = 0; i < num_reg_bytes; i++) {
+    if (bits_[i] != SafepointTable::kNoRegisters) return true;
+  }
+  return false;
+}
+
+
+bool SafepointEntry::HasRegisterAt(int reg_index) const {
+  ASSERT(is_valid());
+  ASSERT(reg_index >= 0 && reg_index < kNumSafepointRegisters);
+  int byte_index = reg_index >> kBitsPerByteLog2;
+  int bit_index = reg_index & (kBitsPerByte - 1);
+  return (bits_[byte_index] & (1 << bit_index)) != 0;
+}
+
+
 SafepointTable::SafepointTable(Code* code) {
   ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION);
   code_ = code;
@@ -41,45 +64,39 @@ SafepointTable::SafepointTable(Code* code) {
   entries_ = pc_and_deoptimization_indexes_ +
             (length_ * kPcAndDeoptimizationIndexSize);
   ASSERT(entry_size_ > 0);
-  ASSERT_EQ(DeoptimizationIndexField::max(), Safepoint::kNoDeoptimizationIndex);
+  ASSERT_EQ(SafepointEntry::DeoptimizationIndexField::max(),
+            Safepoint::kNoDeoptimizationIndex);
 }
 
 
-bool SafepointTable::HasRegisters(uint8_t* entry) {
-  ASSERT(IsAligned(kNumSafepointRegisters, kBitsPerByte));
-  const int num_reg_bytes = kNumSafepointRegisters >> kBitsPerByteLog2;
-  for (int i = 0; i < num_reg_bytes; i++) {
-    if (entry[i] != kNoRegisters) return true;
+SafepointEntry SafepointTable::FindEntry(Address pc) const {
+  unsigned pc_offset = static_cast<unsigned>(pc - code_->instruction_start());
+  for (unsigned i = 0; i < length(); i++) {
+    // TODO(kasperl): Replace the linear search with binary search.
+    if (GetPcOffset(i) == pc_offset) return GetEntry(i);
   }
-  return false;
-}
-
-
-bool SafepointTable::HasRegisterAt(uint8_t* entry, int reg_index) {
-  ASSERT(reg_index >= 0 && reg_index < kNumSafepointRegisters);
-  int byte_index = reg_index >> kBitsPerByteLog2;
-  int bit_index = reg_index & (kBitsPerByte - 1);
-  return (entry[byte_index] & (1 << bit_index)) != 0;
+  return SafepointEntry();
 }
 
 
 void SafepointTable::PrintEntry(unsigned index) const {
   disasm::NameConverter converter;
-  uint8_t* entry = GetEntry(index);
+  SafepointEntry entry = GetEntry(index);
+  uint8_t* bits = entry.bits();
 
   // Print the stack slot bits.
   if (entry_size_ > 0) {
     ASSERT(IsAligned(kNumSafepointRegisters, kBitsPerByte));
     const int first = kNumSafepointRegisters >> kBitsPerByteLog2;
     int last = entry_size_ - 1;
-    for (int i = first; i < last; i++) PrintBits(entry[i], kBitsPerByte);
+    for (int i = first; i < last; i++) PrintBits(bits[i], kBitsPerByte);
     int last_bits = code_->stack_slots() - ((last - first) * kBitsPerByte);
-    PrintBits(entry[last], last_bits);
+    PrintBits(bits[last], last_bits);
 
     // Print the registers (if any).
-    if (!HasRegisters(entry)) return;
+    if (!entry.HasRegisters()) return;
     for (int j = 0; j < kNumSafepointRegisters; j++) {
-      if (HasRegisterAt(entry, j)) {
+      if (entry.HasRegisterAt(j)) {
         PrintF(" | %s", converter.NameOfCPURegister(j));
       }
     }
@@ -95,6 +112,11 @@ void SafepointTable::PrintBits(uint8_t byte, int digits) {
 }
 
 
+void Safepoint::DefinePointerRegister(Register reg) {
+  registers_->Add(reg.code());
+}
+
+
 Safepoint SafepointTableBuilder::DefineSafepoint(Assembler* assembler,
                                                  int deoptimization_index) {
   ASSERT(deoptimization_index != -1);
@@ -102,6 +124,7 @@ Safepoint SafepointTableBuilder::DefineSafepoint(Assembler* assembler,
   pc_and_deoptimization_index.pc = assembler->pc_offset();
   pc_and_deoptimization_index.deoptimization_index = deoptimization_index;
   pc_and_deoptimization_index.pc_after_gap = assembler->pc_offset();
+  pc_and_deoptimization_index.arguments = 0;
   deoptimization_info_.Add(pc_and_deoptimization_index);
   indexes_.Add(new ZoneList<int>(8));
   registers_.Add(NULL);
@@ -112,11 +135,12 @@ Safepoint SafepointTableBuilder::DefineSafepoint(Assembler* assembler,
 Safepoint SafepointTableBuilder::DefineSafepointWithRegisters(
     Assembler* assembler, int arguments, int deoptimization_index) {
   ASSERT(deoptimization_index != -1);
-  ASSERT(arguments == 0);  // Only case that works for now.
+  ASSERT(arguments >= 0);
   DeoptimizationInfo pc_and_deoptimization_index;
   pc_and_deoptimization_index.pc = assembler->pc_offset();
   pc_and_deoptimization_index.deoptimization_index = deoptimization_index;
   pc_and_deoptimization_index.pc_after_gap = assembler->pc_offset();
+  pc_and_deoptimization_index.arguments = arguments;
   deoptimization_info_.Add(pc_and_deoptimization_index);
   indexes_.Add(new ZoneList<int>(8));
   registers_.Add(new ZoneList<int>(4));
@@ -152,7 +176,7 @@ void SafepointTableBuilder::Emit(Assembler* assembler, int bits_per_entry) {
   // pc after gap information.
   for (int i = 0; i < length; i++) {
     assembler->dd(deoptimization_info_[i].pc);
-    assembler->dd(EncodeDeoptimizationIndexAndGap(deoptimization_info_[i]));
+    assembler->dd(EncodeExceptPC(deoptimization_info_[i]));
   }
 
   // Emit table of bitmaps.
@@ -197,12 +221,12 @@ void SafepointTableBuilder::Emit(Assembler* assembler, int bits_per_entry) {
 }
 
 
-uint32_t SafepointTableBuilder::EncodeDeoptimizationIndexAndGap(
-    DeoptimizationInfo info) {
+uint32_t SafepointTableBuilder::EncodeExceptPC(const DeoptimizationInfo& info) {
   unsigned index = info.deoptimization_index;
   unsigned gap_size = info.pc_after_gap - info.pc;
-  uint32_t encoding = SafepointTable::DeoptimizationIndexField::encode(index);
-  encoding |= SafepointTable::GapCodeSizeField::encode(gap_size);
+  uint32_t encoding = SafepointEntry::DeoptimizationIndexField::encode(index);
+  encoding |= SafepointEntry::GapCodeSizeField::encode(gap_size);
+  encoding |= SafepointEntry::ArgumentsField::encode(info.arguments);
   return encoding;
 }
 
index d92018c..6e5e0d8 100644 (file)
 
 #include "v8.h"
 
-#include "macro-assembler.h"
+#include "heap.h"
 #include "zone.h"
 #include "zone-inl.h"
 
 namespace v8 {
 namespace internal {
 
-class SafepointTable BASE_EMBEDDED {
+struct Register;
+
+class SafepointEntry BASE_EMBEDDED {
  public:
-  explicit SafepointTable(Code* code);
+  SafepointEntry() : info_(0), bits_(NULL) {}
 
-  int size() const {
-    return kHeaderSize +
-           (length_ * (kPcAndDeoptimizationIndexSize + entry_size_)); }
-  unsigned length() const { return length_; }
-  unsigned entry_size() const { return entry_size_; }
+  SafepointEntry(unsigned info, uint8_t* bits) : info_(info), bits_(bits) {
+    ASSERT(is_valid());
+  }
 
-  unsigned GetPcOffset(unsigned index) const {
-    ASSERT(index < length_);
-    return Memory::uint32_at(GetPcOffsetLocation(index));
+  bool is_valid() const { return bits_ != NULL; }
+
+  bool Equals(const SafepointEntry& other) const {
+    return info_ == other.info_ && bits_ == other.bits_;
   }
 
-  int GetDeoptimizationIndex(unsigned index) const {
-    ASSERT(index < length_);
-    unsigned value = Memory::uint32_at(GetDeoptimizationLocation(index));
-    return DeoptimizationIndexField::decode(value);
+  void Reset() {
+    info_ = 0;
+    bits_ = NULL;
   }
 
-  unsigned GetGapCodeSize(unsigned index) const {
-    ASSERT(index < length_);
-    unsigned value = Memory::uint32_at(GetDeoptimizationLocation(index));
-    return GapCodeSizeField::decode(value);
+  int deoptimization_index() const {
+    ASSERT(is_valid());
+    return DeoptimizationIndexField::decode(info_);
   }
 
-  uint8_t* GetEntry(unsigned index) const {
-    ASSERT(index < length_);
-    return &Memory::uint8_at(entries_ + (index * entry_size_));
+  int gap_code_size() const {
+    ASSERT(is_valid());
+    return GapCodeSizeField::decode(info_);
   }
 
+  int argument_count() const {
+    ASSERT(is_valid());
+    return ArgumentsField::decode(info_);
+  }
+
+  uint8_t* bits() {
+    ASSERT(is_valid());
+    return bits_;
+  }
+
+  bool HasRegisters() const;
+  bool HasRegisterAt(int reg_index) const;
+
   // Reserve 13 bits for the gap code size. On ARM a constant pool can be
   // emitted when generating the gap code. The size of the const pool is less
   // than what can be represented in 12 bits, so 13 bits gives room for having
   // instructions before potentially emitting a constant pool.
   static const int kGapCodeSizeBits = 13;
-  static const int kDeoptIndexBits = 32 - kGapCodeSizeBits;
+  static const int kArgumentsFieldBits = 3;
+  static const int kDeoptIndexBits =
+      32 - kGapCodeSizeBits - kArgumentsFieldBits;
   class GapCodeSizeField: public BitField<unsigned, 0, kGapCodeSizeBits> {};
-  class DeoptimizationIndexField: public BitField<int, kGapCodeSizeBits, kDeoptIndexBits> {};  // NOLINT
+  class DeoptimizationIndexField: public BitField<int,
+                                                  kGapCodeSizeBits,
+                                                  kDeoptIndexBits> {};  // NOLINT
+  class ArgumentsField: public BitField<unsigned,
+                                        kGapCodeSizeBits + kDeoptIndexBits,
+                                        kArgumentsFieldBits> {};  // NOLINT
+ private:
+  unsigned info_;
+  uint8_t* bits_;
+};
+
+
+class SafepointTable BASE_EMBEDDED {
+ public:
+  explicit SafepointTable(Code* code);
 
-  static bool HasRegisters(uint8_t* entry);
-  static bool HasRegisterAt(uint8_t* entry, int reg_index);
+  int size() const {
+    return kHeaderSize +
+           (length_ * (kPcAndDeoptimizationIndexSize + entry_size_)); }
+  unsigned length() const { return length_; }
+  unsigned entry_size() const { return entry_size_; }
+
+  unsigned GetPcOffset(unsigned index) const {
+    ASSERT(index < length_);
+    return Memory::uint32_at(GetPcOffsetLocation(index));
+  }
+
+  SafepointEntry GetEntry(unsigned index) const {
+    ASSERT(index < length_);
+    unsigned info = Memory::uint32_at(GetInfoLocation(index));
+    uint8_t* bits = &Memory::uint8_at(entries_ + (index * entry_size_));
+    return SafepointEntry(info, bits);
+  }
+
+  // Returns the entry for the given pc.
+  SafepointEntry FindEntry(Address pc) const;
 
   void PrintEntry(unsigned index) const;
 
@@ -100,7 +146,7 @@ class SafepointTable BASE_EMBEDDED {
            (index * kPcAndDeoptimizationIndexSize);
   }
 
-  Address GetDeoptimizationLocation(unsigned index) const {
+  Address GetInfoLocation(unsigned index) const {
     return GetPcOffsetLocation(index) + kPcSize;
   }
 
@@ -115,16 +161,19 @@ class SafepointTable BASE_EMBEDDED {
   Address entries_;
 
   friend class SafepointTableBuilder;
+  friend class SafepointEntry;
+
+  DISALLOW_COPY_AND_ASSIGN(SafepointTable);
 };
 
 
 class Safepoint BASE_EMBEDDED {
  public:
   static const int kNoDeoptimizationIndex =
-      (1 << (SafepointTable::kDeoptIndexBits)) - 1;
+      (1 << (SafepointEntry::kDeoptIndexBits)) - 1;
 
   void DefinePointerSlot(int index) { indexes_->Add(index); }
-  void DefinePointerRegister(Register reg) { registers_->Add(reg.code()); }
+  void DefinePointerRegister(Register reg);
 
  private:
   Safepoint(ZoneList<int>* indexes, ZoneList<int>* registers) :
@@ -177,9 +226,10 @@ class SafepointTableBuilder BASE_EMBEDDED {
     unsigned pc;
     unsigned deoptimization_index;
     unsigned pc_after_gap;
+    unsigned arguments;
   };
 
-  uint32_t EncodeDeoptimizationIndexAndGap(DeoptimizationInfo info);
+  uint32_t EncodeExceptPC(const DeoptimizationInfo& info);
 
   ZoneList<DeoptimizationInfo> deoptimization_info_;
   ZoneList<ZoneList<int>*> indexes_;