433b9b8456dc869ad6774e166b0bb9f8509c9c03
[platform/upstream/v8.git] / src / assembler.h
1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
2 // All Rights Reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // - Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 //
11 // - Redistribution in binary form must reproduce the above copyright
12 // notice, this list of conditions and the following disclaimer in the
13 // documentation and/or other materials provided with the distribution.
14 //
15 // - Neither the name of Sun Microsystems or the names of contributors may
16 // be used to endorse or promote products derived from this software without
17 // specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20 // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 // The original source code covered by the above license above has been
32 // modified significantly by Google Inc.
33 // Copyright 2012 the V8 project authors. All rights reserved.
34
35 #ifndef V8_ASSEMBLER_H_
36 #define V8_ASSEMBLER_H_
37
38 #include "src/allocation.h"
39 #include "src/builtins.h"
40 #include "src/isolate.h"
41 #include "src/runtime/runtime.h"
42 #include "src/token.h"
43
44 namespace v8 {
45
46 // Forward declarations.
47 class ApiFunction;
48
49 namespace internal {
50
51 // Forward declarations.
52 class StatsCounter;
53
54 // -----------------------------------------------------------------------------
55 // Platform independent assembler base class.
56
57 class AssemblerBase: public Malloced {
58  public:
59   AssemblerBase(Isolate* isolate, void* buffer, int buffer_size);
60   virtual ~AssemblerBase();
61
62   Isolate* isolate() const { return isolate_; }
63   int jit_cookie() const { return jit_cookie_; }
64
65   bool emit_debug_code() const { return emit_debug_code_; }
66   void set_emit_debug_code(bool value) { emit_debug_code_ = value; }
67
68   bool serializer_enabled() const { return serializer_enabled_; }
69   void enable_serializer() { serializer_enabled_ = true; }
70
71   bool predictable_code_size() const { return predictable_code_size_; }
72   void set_predictable_code_size(bool value) { predictable_code_size_ = value; }
73
74   uint64_t enabled_cpu_features() const { return enabled_cpu_features_; }
75   void set_enabled_cpu_features(uint64_t features) {
76     enabled_cpu_features_ = features;
77   }
78   bool IsEnabled(CpuFeature f) {
79     return (enabled_cpu_features_ & (static_cast<uint64_t>(1) << f)) != 0;
80   }
81
82   bool is_constant_pool_available() const {
83     if (FLAG_enable_embedded_constant_pool) {
84       return constant_pool_available_;
85     } else {
86       // Embedded constant pool not supported on this architecture.
87       UNREACHABLE();
88       return false;
89     }
90   }
91
92   // Overwrite a host NaN with a quiet target NaN.  Used by mksnapshot for
93   // cross-snapshotting.
94   static void QuietNaN(HeapObject* nan) { }
95
96   int pc_offset() const { return static_cast<int>(pc_ - buffer_); }
97
98   // This function is called when code generation is aborted, so that
99   // the assembler could clean up internal data structures.
100   virtual void AbortedCodeGeneration() { }
101
102   static const int kMinimalBufferSize = 4*KB;
103
104   static void FlushICache(Isolate* isolate, void* start, size_t size);
105
106   // TODO(all): Help get rid of this one.
107   static void FlushICacheWithoutIsolate(void* start, size_t size);
108
109  protected:
110   // The buffer into which code and relocation info are generated. It could
111   // either be owned by the assembler or be provided externally.
112   byte* buffer_;
113   int buffer_size_;
114   bool own_buffer_;
115
116   void set_constant_pool_available(bool available) {
117     if (FLAG_enable_embedded_constant_pool) {
118       constant_pool_available_ = available;
119     } else {
120       // Embedded constant pool not supported on this architecture.
121       UNREACHABLE();
122     }
123   }
124
125   // The program counter, which points into the buffer above and moves forward.
126   byte* pc_;
127
128  private:
129   Isolate* isolate_;
130   int jit_cookie_;
131   uint64_t enabled_cpu_features_;
132   bool emit_debug_code_;
133   bool predictable_code_size_;
134   bool serializer_enabled_;
135
136   // Indicates whether the constant pool can be accessed, which is only possible
137   // if the pp register points to the current code object's constant pool.
138   bool constant_pool_available_;
139
140   // Constant pool.
141   friend class FrameAndConstantPoolScope;
142   friend class ConstantPoolUnavailableScope;
143 };
144
145
146 // Avoids emitting debug code during the lifetime of this scope object.
147 class DontEmitDebugCodeScope BASE_EMBEDDED {
148  public:
149   explicit DontEmitDebugCodeScope(AssemblerBase* assembler)
150       : assembler_(assembler), old_value_(assembler->emit_debug_code()) {
151     assembler_->set_emit_debug_code(false);
152   }
153   ~DontEmitDebugCodeScope() {
154     assembler_->set_emit_debug_code(old_value_);
155   }
156  private:
157   AssemblerBase* assembler_;
158   bool old_value_;
159 };
160
161
162 // Avoids using instructions that vary in size in unpredictable ways between the
163 // snapshot and the running VM.
164 class PredictableCodeSizeScope {
165  public:
166   explicit PredictableCodeSizeScope(AssemblerBase* assembler);
167   PredictableCodeSizeScope(AssemblerBase* assembler, int expected_size);
168   ~PredictableCodeSizeScope();
169   void ExpectSize(int expected_size) { expected_size_ = expected_size; }
170
171  private:
172   AssemblerBase* assembler_;
173   int expected_size_;
174   int start_offset_;
175   bool old_value_;
176 };
177
178
179 // Enable a specified feature within a scope.
180 class CpuFeatureScope BASE_EMBEDDED {
181  public:
182 #ifdef DEBUG
183   CpuFeatureScope(AssemblerBase* assembler, CpuFeature f);
184   ~CpuFeatureScope();
185
186  private:
187   AssemblerBase* assembler_;
188   uint64_t old_enabled_;
189 #else
190   CpuFeatureScope(AssemblerBase* assembler, CpuFeature f) {}
191 #endif
192 };
193
194
195 // CpuFeatures keeps track of which features are supported by the target CPU.
196 // Supported features must be enabled by a CpuFeatureScope before use.
197 // Example:
198 //   if (assembler->IsSupported(SSE3)) {
199 //     CpuFeatureScope fscope(assembler, SSE3);
200 //     // Generate code containing SSE3 instructions.
201 //   } else {
202 //     // Generate alternative code.
203 //   }
204 class CpuFeatures : public AllStatic {
205  public:
206   static void Probe(bool cross_compile) {
207     STATIC_ASSERT(NUMBER_OF_CPU_FEATURES <= kBitsPerInt);
208     if (initialized_) return;
209     initialized_ = true;
210     ProbeImpl(cross_compile);
211   }
212
213   static unsigned SupportedFeatures() {
214     Probe(false);
215     return supported_;
216   }
217
218   static bool IsSupported(CpuFeature f) {
219     return (supported_ & (1u << f)) != 0;
220   }
221
222   static inline bool SupportsCrankshaft();
223
224   static inline unsigned cache_line_size() {
225     DCHECK(cache_line_size_ != 0);
226     return cache_line_size_;
227   }
228
229   static void PrintTarget();
230   static void PrintFeatures();
231
232   // Flush instruction cache.
233   static void FlushICache(void* start, size_t size);
234
235  private:
236   // Platform-dependent implementation.
237   static void ProbeImpl(bool cross_compile);
238
239   static unsigned supported_;
240   static unsigned cache_line_size_;
241   static bool initialized_;
242   friend class ExternalReference;
243   DISALLOW_COPY_AND_ASSIGN(CpuFeatures);
244 };
245
246
247 // -----------------------------------------------------------------------------
248 // Labels represent pc locations; they are typically jump or call targets.
249 // After declaration, a label can be freely used to denote known or (yet)
250 // unknown pc location. Assembler::bind() is used to bind a label to the
251 // current pc. A label can be bound only once.
252
253 class Label {
254  public:
255   enum Distance {
256     kNear, kFar
257   };
258
259   INLINE(Label()) {
260     Unuse();
261     UnuseNear();
262   }
263
264   INLINE(~Label()) {
265     DCHECK(!is_linked());
266     DCHECK(!is_near_linked());
267   }
268
269   INLINE(void Unuse()) { pos_ = 0; }
270   INLINE(void UnuseNear()) { near_link_pos_ = 0; }
271
272   INLINE(bool is_bound() const) { return pos_ <  0; }
273   INLINE(bool is_unused() const) { return pos_ == 0 && near_link_pos_ == 0; }
274   INLINE(bool is_linked() const) { return pos_ >  0; }
275   INLINE(bool is_near_linked() const) { return near_link_pos_ > 0; }
276
277   // Returns the position of bound or linked labels. Cannot be used
278   // for unused labels.
279   int pos() const;
280   int near_link_pos() const { return near_link_pos_ - 1; }
281
282  private:
283   // pos_ encodes both the binding state (via its sign)
284   // and the binding position (via its value) of a label.
285   //
286   // pos_ <  0  bound label, pos() returns the jump target position
287   // pos_ == 0  unused label
288   // pos_ >  0  linked label, pos() returns the last reference position
289   int pos_;
290
291   // Behaves like |pos_| in the "> 0" case, but for near jumps to this label.
292   int near_link_pos_;
293
294   void bind_to(int pos)  {
295     pos_ = -pos - 1;
296     DCHECK(is_bound());
297   }
298   void link_to(int pos, Distance distance = kFar) {
299     if (distance == kNear) {
300       near_link_pos_ = pos + 1;
301       DCHECK(is_near_linked());
302     } else {
303       pos_ = pos + 1;
304       DCHECK(is_linked());
305     }
306   }
307
308   friend class Assembler;
309   friend class Displacement;
310   friend class RegExpMacroAssemblerIrregexp;
311
312 #if V8_TARGET_ARCH_ARM64
313   // On ARM64, the Assembler keeps track of pointers to Labels to resolve
314   // branches to distant targets. Copying labels would confuse the Assembler.
315   DISALLOW_COPY_AND_ASSIGN(Label);  // NOLINT
316 #endif
317 };
318
319
320 enum SaveFPRegsMode { kDontSaveFPRegs, kSaveFPRegs };
321
322 // Specifies whether to perform icache flush operations on RelocInfo updates.
323 // If FLUSH_ICACHE_IF_NEEDED, the icache will always be flushed if an
324 // instruction was modified. If SKIP_ICACHE_FLUSH the flush will always be
325 // skipped (only use this if you will flush the icache manually before it is
326 // executed).
327 enum ICacheFlushMode { FLUSH_ICACHE_IF_NEEDED, SKIP_ICACHE_FLUSH };
328
329 // -----------------------------------------------------------------------------
330 // Relocation information
331
332
333 // Relocation information consists of the address (pc) of the datum
334 // to which the relocation information applies, the relocation mode
335 // (rmode), and an optional data field. The relocation mode may be
336 // "descriptive" and not indicate a need for relocation, but simply
337 // describe a property of the datum. Such rmodes are useful for GC
338 // and nice disassembly output.
339
340 class RelocInfo {
341  public:
342   // The constant kNoPosition is used with the collecting of source positions
343   // in the relocation information. Two types of source positions are collected
344   // "position" (RelocMode position) and "statement position" (RelocMode
345   // statement_position). The "position" is collected at places in the source
346   // code which are of interest when making stack traces to pin-point the source
347   // location of a stack frame as close as possible. The "statement position" is
348   // collected at the beginning at each statement, and is used to indicate
349   // possible break locations. kNoPosition is used to indicate an
350   // invalid/uninitialized position value.
351   static const int kNoPosition = -1;
352
353   // This string is used to add padding comments to the reloc info in cases
354   // where we are not sure to have enough space for patching in during
355   // lazy deoptimization. This is the case if we have indirect calls for which
356   // we do not normally record relocation info.
357   static const char* const kFillerCommentString;
358
359   // The minimum size of a comment is equal to two bytes for the extra tagged
360   // pc and kPointerSize for the actual pointer to the comment.
361   static const int kMinRelocCommentSize = 2 + kPointerSize;
362
363   // The maximum size for a call instruction including pc-jump.
364   static const int kMaxCallSize = 6;
365
366   // The maximum pc delta that will use the short encoding.
367   static const int kMaxSmallPCDelta;
368
369   enum Mode {
370     // Please note the order is important (see IsCodeTarget, IsGCRelocMode).
371     CODE_TARGET,  // Code target which is not any of the above.
372     CODE_TARGET_WITH_ID,
373     CONSTRUCT_CALL,  // code target that is a call to a JavaScript constructor.
374     DEBUGGER_STATEMENT,  // Code target for the debugger statement.
375     EMBEDDED_OBJECT,
376     CELL,
377
378     // Everything after runtime_entry (inclusive) is not GC'ed.
379     RUNTIME_ENTRY,
380     COMMENT,
381     POSITION,            // See comment for kNoPosition above.
382     STATEMENT_POSITION,  // See comment for kNoPosition above.
383
384     // Additional code inserted for debug break slot.
385     DEBUG_BREAK_SLOT_AT_POSITION,
386     DEBUG_BREAK_SLOT_AT_RETURN,
387     DEBUG_BREAK_SLOT_AT_CALL,
388     DEBUG_BREAK_SLOT_AT_CONSTRUCT_CALL,
389
390     EXTERNAL_REFERENCE,  // The address of an external C++ function.
391     INTERNAL_REFERENCE,  // An address inside the same function.
392
393     // Encoded internal reference, used only on MIPS, MIPS64 and PPC.
394     INTERNAL_REFERENCE_ENCODED,
395
396     // Continuation points for a generator yield.
397     GENERATOR_CONTINUATION,
398
399     // Marks constant and veneer pools. Only used on ARM and ARM64.
400     // They use a custom noncompact encoding.
401     CONST_POOL,
402     VENEER_POOL,
403
404     DEOPT_REASON,  // Deoptimization reason index.
405
406     // This is not an actual reloc mode, but used to encode a long pc jump that
407     // cannot be encoded as part of another record.
408     PC_JUMP,
409
410     // Pseudo-types
411     NUMBER_OF_MODES,
412     NONE32,             // never recorded 32-bit value
413     NONE64,             // never recorded 64-bit value
414     CODE_AGE_SEQUENCE,  // Not stored in RelocInfo array, used explictly by
415                         // code aging.
416
417     FIRST_REAL_RELOC_MODE = CODE_TARGET,
418     LAST_REAL_RELOC_MODE = VENEER_POOL,
419     LAST_CODE_ENUM = DEBUGGER_STATEMENT,
420     LAST_GCED_ENUM = CELL,
421   };
422
423   STATIC_ASSERT(NUMBER_OF_MODES <= kBitsPerInt);
424
425   RelocInfo() {}
426
427   RelocInfo(byte* pc, Mode rmode, intptr_t data, Code* host)
428       : pc_(pc), rmode_(rmode), data_(data), host_(host) {
429   }
430
431   static inline bool IsRealRelocMode(Mode mode) {
432     return mode >= FIRST_REAL_RELOC_MODE &&
433         mode <= LAST_REAL_RELOC_MODE;
434   }
435   static inline bool IsConstructCall(Mode mode) {
436     return mode == CONSTRUCT_CALL;
437   }
438   static inline bool IsCodeTarget(Mode mode) {
439     return mode <= LAST_CODE_ENUM;
440   }
441   static inline bool IsEmbeddedObject(Mode mode) {
442     return mode == EMBEDDED_OBJECT;
443   }
444   static inline bool IsCell(Mode mode) { return mode == CELL; }
445   static inline bool IsRuntimeEntry(Mode mode) {
446     return mode == RUNTIME_ENTRY;
447   }
448   // Is the relocation mode affected by GC?
449   static inline bool IsGCRelocMode(Mode mode) {
450     return mode <= LAST_GCED_ENUM;
451   }
452   static inline bool IsComment(Mode mode) {
453     return mode == COMMENT;
454   }
455   static inline bool IsConstPool(Mode mode) {
456     return mode == CONST_POOL;
457   }
458   static inline bool IsVeneerPool(Mode mode) {
459     return mode == VENEER_POOL;
460   }
461   static inline bool IsDeoptReason(Mode mode) {
462     return mode == DEOPT_REASON;
463   }
464   static inline bool IsPosition(Mode mode) {
465     return mode == POSITION || mode == STATEMENT_POSITION;
466   }
467   static inline bool IsStatementPosition(Mode mode) {
468     return mode == STATEMENT_POSITION;
469   }
470   static inline bool IsExternalReference(Mode mode) {
471     return mode == EXTERNAL_REFERENCE;
472   }
473   static inline bool IsInternalReference(Mode mode) {
474     return mode == INTERNAL_REFERENCE;
475   }
476   static inline bool IsInternalReferenceEncoded(Mode mode) {
477     return mode == INTERNAL_REFERENCE_ENCODED;
478   }
479   static inline bool IsDebugBreakSlot(Mode mode) {
480     return IsDebugBreakSlotAtPosition(mode) || IsDebugBreakSlotAtReturn(mode) ||
481            IsDebugBreakSlotAtCall(mode) ||
482            IsDebugBreakSlotAtConstructCall(mode);
483   }
484   static inline bool IsDebugBreakSlotAtPosition(Mode mode) {
485     return mode == DEBUG_BREAK_SLOT_AT_POSITION;
486   }
487   static inline bool IsDebugBreakSlotAtReturn(Mode mode) {
488     return mode == DEBUG_BREAK_SLOT_AT_RETURN;
489   }
490   static inline bool IsDebugBreakSlotAtCall(Mode mode) {
491     return mode == DEBUG_BREAK_SLOT_AT_CALL;
492   }
493   static inline bool IsDebugBreakSlotAtConstructCall(Mode mode) {
494     return mode == DEBUG_BREAK_SLOT_AT_CONSTRUCT_CALL;
495   }
496   static inline bool IsDebuggerStatement(Mode mode) {
497     return mode == DEBUGGER_STATEMENT;
498   }
499   static inline bool IsNone(Mode mode) {
500     return mode == NONE32 || mode == NONE64;
501   }
502   static inline bool IsCodeAgeSequence(Mode mode) {
503     return mode == CODE_AGE_SEQUENCE;
504   }
505   static inline bool IsGeneratorContinuation(Mode mode) {
506     return mode == GENERATOR_CONTINUATION;
507   }
508   static inline int ModeMask(Mode mode) { return 1 << mode; }
509
510   // Accessors
511   byte* pc() const { return pc_; }
512   void set_pc(byte* pc) { pc_ = pc; }
513   Mode rmode() const {  return rmode_; }
514   intptr_t data() const { return data_; }
515   Code* host() const { return host_; }
516   void set_host(Code* host) { host_ = host; }
517
518   // Apply a relocation by delta bytes. When the code object is moved, PC
519   // relative addresses have to be updated as well as absolute addresses
520   // inside the code (internal references).
521   // Do not forget to flush the icache afterwards!
522   INLINE(void apply(intptr_t delta));
523
524   // Is the pointer this relocation info refers to coded like a plain pointer
525   // or is it strange in some way (e.g. relative or patched into a series of
526   // instructions).
527   bool IsCodedSpecially();
528
529   // If true, the pointer this relocation info refers to is an entry in the
530   // constant pool, otherwise the pointer is embedded in the instruction stream.
531   bool IsInConstantPool();
532
533   static int DebugBreakCallArgumentsCount(intptr_t data);
534
535   // Read/modify the code target in the branch/call instruction
536   // this relocation applies to;
537   // can only be called if IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)
538   INLINE(Address target_address());
539   INLINE(void set_target_address(Address target,
540                                  WriteBarrierMode write_barrier_mode =
541                                      UPDATE_WRITE_BARRIER,
542                                  ICacheFlushMode icache_flush_mode =
543                                      FLUSH_ICACHE_IF_NEEDED));
544   INLINE(Object* target_object());
545   INLINE(Handle<Object> target_object_handle(Assembler* origin));
546   INLINE(void set_target_object(Object* target,
547                                 WriteBarrierMode write_barrier_mode =
548                                     UPDATE_WRITE_BARRIER,
549                                 ICacheFlushMode icache_flush_mode =
550                                     FLUSH_ICACHE_IF_NEEDED));
551   INLINE(Address target_runtime_entry(Assembler* origin));
552   INLINE(void set_target_runtime_entry(Address target,
553                                        WriteBarrierMode write_barrier_mode =
554                                            UPDATE_WRITE_BARRIER,
555                                        ICacheFlushMode icache_flush_mode =
556                                            FLUSH_ICACHE_IF_NEEDED));
557   INLINE(Cell* target_cell());
558   INLINE(Handle<Cell> target_cell_handle());
559   INLINE(void set_target_cell(Cell* cell,
560                               WriteBarrierMode write_barrier_mode =
561                                   UPDATE_WRITE_BARRIER,
562                               ICacheFlushMode icache_flush_mode =
563                                   FLUSH_ICACHE_IF_NEEDED));
564   INLINE(Handle<Object> code_age_stub_handle(Assembler* origin));
565   INLINE(Code* code_age_stub());
566   INLINE(void set_code_age_stub(Code* stub,
567                                 ICacheFlushMode icache_flush_mode =
568                                     FLUSH_ICACHE_IF_NEEDED));
569
570   // Returns the address of the constant pool entry where the target address
571   // is held.  This should only be called if IsInConstantPool returns true.
572   INLINE(Address constant_pool_entry_address());
573
574   // Read the address of the word containing the target_address in an
575   // instruction stream.  What this means exactly is architecture-independent.
576   // The only architecture-independent user of this function is the serializer.
577   // The serializer uses it to find out how many raw bytes of instruction to
578   // output before the next target.  Architecture-independent code shouldn't
579   // dereference the pointer it gets back from this.
580   INLINE(Address target_address_address());
581
582   // This indicates how much space a target takes up when deserializing a code
583   // stream.  For most architectures this is just the size of a pointer.  For
584   // an instruction like movw/movt where the target bits are mixed into the
585   // instruction bits the size of the target will be zero, indicating that the
586   // serializer should not step forwards in memory after a target is resolved
587   // and written.  In this case the target_address_address function above
588   // should return the end of the instructions to be patched, allowing the
589   // deserializer to deserialize the instructions as raw bytes and put them in
590   // place, ready to be patched with the target.
591   INLINE(int target_address_size());
592
593   // Read the reference in the instruction this relocation
594   // applies to; can only be called if rmode_ is EXTERNAL_REFERENCE.
595   INLINE(Address target_external_reference());
596
597   // Read the reference in the instruction this relocation
598   // applies to; can only be called if rmode_ is INTERNAL_REFERENCE.
599   INLINE(Address target_internal_reference());
600
601   // Return the reference address this relocation applies to;
602   // can only be called if rmode_ is INTERNAL_REFERENCE.
603   INLINE(Address target_internal_reference_address());
604
605   // Read/modify the address of a call instruction. This is used to relocate
606   // the break points where straight-line code is patched with a call
607   // instruction.
608   INLINE(Address debug_call_address());
609   INLINE(void set_debug_call_address(Address target));
610
611   // Wipe out a relocation to a fixed value, used for making snapshots
612   // reproducible.
613   INLINE(void WipeOut());
614
615   template<typename StaticVisitor> inline void Visit(Heap* heap);
616   inline void Visit(Isolate* isolate, ObjectVisitor* v);
617
618   // Patch the code with a call.
619   void PatchCodeWithCall(Address target, int guard_bytes);
620
621   // Check whether this return sequence has been patched
622   // with a call to the debugger.
623   INLINE(bool IsPatchedReturnSequence());
624
625   // Check whether this debug break slot has been patched with a call to the
626   // debugger.
627   INLINE(bool IsPatchedDebugBreakSlotSequence());
628
629 #ifdef DEBUG
630   // Check whether the given code contains relocation information that
631   // either is position-relative or movable by the garbage collector.
632   static bool RequiresRelocation(const CodeDesc& desc);
633 #endif
634
635 #ifdef ENABLE_DISASSEMBLER
636   // Printing
637   static const char* RelocModeName(Mode rmode);
638   void Print(Isolate* isolate, std::ostream& os);  // NOLINT
639 #endif  // ENABLE_DISASSEMBLER
640 #ifdef VERIFY_HEAP
641   void Verify(Isolate* isolate);
642 #endif
643
644   static const int kCodeTargetMask = (1 << (LAST_CODE_ENUM + 1)) - 1;
645   static const int kPositionMask = 1 << POSITION | 1 << STATEMENT_POSITION;
646   static const int kDataMask =
647       (1 << CODE_TARGET_WITH_ID) | kPositionMask | (1 << COMMENT);
648   static const int kDebugBreakSlotMask =
649       1 << DEBUG_BREAK_SLOT_AT_POSITION | 1 << DEBUG_BREAK_SLOT_AT_RETURN |
650       1 << DEBUG_BREAK_SLOT_AT_CALL | 1 << DEBUG_BREAK_SLOT_AT_CONSTRUCT_CALL;
651   static const int kApplyMask;  // Modes affected by apply.  Depends on arch.
652
653  private:
654   // On ARM, note that pc_ is the address of the constant pool entry
655   // to be relocated and not the address of the instruction
656   // referencing the constant pool entry (except when rmode_ ==
657   // comment).
658   byte* pc_;
659   Mode rmode_;
660   intptr_t data_;
661   Code* host_;
662   // External-reference pointers are also split across instruction-pairs
663   // on some platforms, but are accessed via indirect pointers. This location
664   // provides a place for that pointer to exist naturally. Its address
665   // is returned by RelocInfo::target_reference_address().
666   Address reconstructed_adr_ptr_;
667   friend class RelocIterator;
668 };
669
670
671 // RelocInfoWriter serializes a stream of relocation info. It writes towards
672 // lower addresses.
673 class RelocInfoWriter BASE_EMBEDDED {
674  public:
675   RelocInfoWriter()
676       : pos_(NULL),
677         last_pc_(NULL),
678         last_id_(0),
679         last_position_(0),
680         last_mode_(RelocInfo::NUMBER_OF_MODES),
681         next_position_candidate_pos_delta_(0),
682         next_position_candidate_pc_delta_(0),
683         next_position_candidate_flushed_(true) {}
684   RelocInfoWriter(byte* pos, byte* pc)
685       : pos_(pos),
686         last_pc_(pc),
687         last_id_(0),
688         last_position_(0),
689         last_mode_(RelocInfo::NUMBER_OF_MODES),
690         next_position_candidate_pos_delta_(0),
691         next_position_candidate_pc_delta_(0),
692         next_position_candidate_flushed_(true) {}
693
694   byte* pos() const { return pos_; }
695   byte* last_pc() const { return last_pc_; }
696
697   void Write(const RelocInfo* rinfo);
698
699   // Update the state of the stream after reloc info buffer
700   // and/or code is moved while the stream is active.
701   void Reposition(byte* pos, byte* pc) {
702     pos_ = pos;
703     last_pc_ = pc;
704   }
705
706   void Finish() { FlushPosition(); }
707
708   // Max size (bytes) of a written RelocInfo. Longest encoding is
709   // ExtraTag, VariableLengthPCJump, ExtraTag, pc_delta, data_delta.
710   // On ia32 and arm this is 1 + 4 + 1 + 1 + 4 = 11.
711   // On x64 this is 1 + 4 + 1 + 1 + 8 == 15;
712   // Here we use the maximum of the two.
713   static const int kMaxSize = 15;
714
715  private:
716   inline uint32_t WriteLongPCJump(uint32_t pc_delta);
717
718   inline void WriteShortTaggedPC(uint32_t pc_delta, int tag);
719   inline void WriteShortTaggedData(intptr_t data_delta, int tag);
720
721   inline void WriteMode(RelocInfo::Mode rmode);
722   inline void WriteModeAndPC(uint32_t pc_delta, RelocInfo::Mode rmode);
723   inline void WriteIntData(int data_delta);
724   inline void WriteData(intptr_t data_delta);
725   inline void WritePosition(int pc_delta, int pos_delta, RelocInfo::Mode rmode);
726
727   void FlushPosition();
728
729   byte* pos_;
730   byte* last_pc_;
731   int last_id_;
732   int last_position_;
733   RelocInfo::Mode last_mode_;
734   int next_position_candidate_pos_delta_;
735   uint32_t next_position_candidate_pc_delta_;
736   bool next_position_candidate_flushed_;
737
738   DISALLOW_COPY_AND_ASSIGN(RelocInfoWriter);
739 };
740
741
742 // A RelocIterator iterates over relocation information.
743 // Typical use:
744 //
745 //   for (RelocIterator it(code); !it.done(); it.next()) {
746 //     // do something with it.rinfo() here
747 //   }
748 //
749 // A mask can be specified to skip unwanted modes.
750 class RelocIterator: public Malloced {
751  public:
752   // Create a new iterator positioned at
753   // the beginning of the reloc info.
754   // Relocation information with mode k is included in the
755   // iteration iff bit k of mode_mask is set.
756   explicit RelocIterator(Code* code, int mode_mask = -1);
757   explicit RelocIterator(const CodeDesc& desc, int mode_mask = -1);
758
759   // Iteration
760   bool done() const { return done_; }
761   void next();
762
763   // Return pointer valid until next next().
764   RelocInfo* rinfo() {
765     DCHECK(!done());
766     return &rinfo_;
767   }
768
769  private:
770   // Advance* moves the position before/after reading.
771   // *Read* reads from current byte(s) into rinfo_.
772   // *Get* just reads and returns info on current byte.
773   void Advance(int bytes = 1) { pos_ -= bytes; }
774   int AdvanceGetTag();
775   RelocInfo::Mode GetMode();
776
777   void AdvanceReadLongPCJump();
778
779   int GetShortDataTypeTag();
780   void ReadShortTaggedPC();
781   void ReadShortTaggedId();
782   void ReadShortTaggedPosition();
783   void ReadShortTaggedData();
784
785   void AdvanceReadPC();
786   void AdvanceReadId();
787   void AdvanceReadInt();
788   void AdvanceReadPosition();
789   void AdvanceReadData();
790
791   // If the given mode is wanted, set it in rinfo_ and return true.
792   // Else return false. Used for efficiently skipping unwanted modes.
793   bool SetMode(RelocInfo::Mode mode) {
794     return (mode_mask_ & (1 << mode)) ? (rinfo_.rmode_ = mode, true) : false;
795   }
796
797   byte* pos_;
798   byte* end_;
799   byte* code_age_sequence_;
800   RelocInfo rinfo_;
801   bool done_;
802   int mode_mask_;
803   int last_id_;
804   int last_position_;
805   DISALLOW_COPY_AND_ASSIGN(RelocIterator);
806 };
807
808
809 //------------------------------------------------------------------------------
810 // External function
811
812 //----------------------------------------------------------------------------
813 class SCTableReference;
814 class Debug_Address;
815
816
817 // An ExternalReference represents a C++ address used in the generated
818 // code. All references to C++ functions and variables must be encapsulated in
819 // an ExternalReference instance. This is done in order to track the origin of
820 // all external references in the code so that they can be bound to the correct
821 // addresses when deserializing a heap.
822 class ExternalReference BASE_EMBEDDED {
823  public:
824   // Used in the simulator to support different native api calls.
825   enum Type {
826     // Builtin call.
827     // Object* f(v8::internal::Arguments).
828     BUILTIN_CALL,  // default
829
830     // Builtin that takes float arguments and returns an int.
831     // int f(double, double).
832     BUILTIN_COMPARE_CALL,
833
834     // Builtin call that returns floating point.
835     // double f(double, double).
836     BUILTIN_FP_FP_CALL,
837
838     // Builtin call that returns floating point.
839     // double f(double).
840     BUILTIN_FP_CALL,
841
842     // Builtin call that returns floating point.
843     // double f(double, int).
844     BUILTIN_FP_INT_CALL,
845
846     // Direct call to API function callback.
847     // void f(v8::FunctionCallbackInfo&)
848     DIRECT_API_CALL,
849
850     // Call to function callback via InvokeFunctionCallback.
851     // void f(v8::FunctionCallbackInfo&, v8::FunctionCallback)
852     PROFILING_API_CALL,
853
854     // Direct call to accessor getter callback.
855     // void f(Local<Name> property, PropertyCallbackInfo& info)
856     DIRECT_GETTER_CALL,
857
858     // Call to accessor getter callback via InvokeAccessorGetterCallback.
859     // void f(Local<Name> property, PropertyCallbackInfo& info,
860     //     AccessorNameGetterCallback callback)
861     PROFILING_GETTER_CALL
862   };
863
864   static void SetUp();
865   static void InitializeMathExpData();
866   static void TearDownMathExpData();
867
868   typedef void* ExternalReferenceRedirector(void* original, Type type);
869
870   ExternalReference() : address_(NULL) {}
871
872   ExternalReference(Builtins::CFunctionId id, Isolate* isolate);
873
874   ExternalReference(ApiFunction* ptr, Type type, Isolate* isolate);
875
876   ExternalReference(Builtins::Name name, Isolate* isolate);
877
878   ExternalReference(Runtime::FunctionId id, Isolate* isolate);
879
880   ExternalReference(const Runtime::Function* f, Isolate* isolate);
881
882   explicit ExternalReference(StatsCounter* counter);
883
884   ExternalReference(Isolate::AddressId id, Isolate* isolate);
885
886   explicit ExternalReference(const SCTableReference& table_ref);
887
888   // Isolate as an external reference.
889   static ExternalReference isolate_address(Isolate* isolate);
890
891   // One-of-a-kind references. These references are not part of a general
892   // pattern. This means that they have to be added to the
893   // ExternalReferenceTable in serialize.cc manually.
894
895   static ExternalReference incremental_marking_record_write_function(
896       Isolate* isolate);
897   static ExternalReference store_buffer_overflow_function(
898       Isolate* isolate);
899   static ExternalReference delete_handle_scope_extensions(Isolate* isolate);
900
901   static ExternalReference get_date_field_function(Isolate* isolate);
902   static ExternalReference date_cache_stamp(Isolate* isolate);
903
904   static ExternalReference get_make_code_young_function(Isolate* isolate);
905   static ExternalReference get_mark_code_as_executed_function(Isolate* isolate);
906
907   // Deoptimization support.
908   static ExternalReference new_deoptimizer_function(Isolate* isolate);
909   static ExternalReference compute_output_frames_function(Isolate* isolate);
910
911   // Log support.
912   static ExternalReference log_enter_external_function(Isolate* isolate);
913   static ExternalReference log_leave_external_function(Isolate* isolate);
914
915   // Static data in the keyed lookup cache.
916   static ExternalReference keyed_lookup_cache_keys(Isolate* isolate);
917   static ExternalReference keyed_lookup_cache_field_offsets(Isolate* isolate);
918
919   // Static variable Heap::roots_array_start()
920   static ExternalReference roots_array_start(Isolate* isolate);
921
922   // Static variable Heap::allocation_sites_list_address()
923   static ExternalReference allocation_sites_list_address(Isolate* isolate);
924
925   // Static variable StackGuard::address_of_jslimit()
926   static ExternalReference address_of_stack_limit(Isolate* isolate);
927
928   // Static variable StackGuard::address_of_real_jslimit()
929   static ExternalReference address_of_real_stack_limit(Isolate* isolate);
930
931   // Static variable RegExpStack::limit_address()
932   static ExternalReference address_of_regexp_stack_limit(Isolate* isolate);
933
934   // Static variables for RegExp.
935   static ExternalReference address_of_static_offsets_vector(Isolate* isolate);
936   static ExternalReference address_of_regexp_stack_memory_address(
937       Isolate* isolate);
938   static ExternalReference address_of_regexp_stack_memory_size(
939       Isolate* isolate);
940
941   // Static variable Heap::NewSpaceStart()
942   static ExternalReference new_space_start(Isolate* isolate);
943   static ExternalReference new_space_mask(Isolate* isolate);
944
945   // Write barrier.
946   static ExternalReference store_buffer_top(Isolate* isolate);
947
948   // Used for fast allocation in generated code.
949   static ExternalReference new_space_allocation_top_address(Isolate* isolate);
950   static ExternalReference new_space_allocation_limit_address(Isolate* isolate);
951   static ExternalReference old_space_allocation_top_address(Isolate* isolate);
952   static ExternalReference old_space_allocation_limit_address(Isolate* isolate);
953
954   static ExternalReference mod_two_doubles_operation(Isolate* isolate);
955   static ExternalReference power_double_double_function(Isolate* isolate);
956   static ExternalReference power_double_int_function(Isolate* isolate);
957
958   static ExternalReference handle_scope_next_address(Isolate* isolate);
959   static ExternalReference handle_scope_limit_address(Isolate* isolate);
960   static ExternalReference handle_scope_level_address(Isolate* isolate);
961
962   static ExternalReference scheduled_exception_address(Isolate* isolate);
963   static ExternalReference address_of_pending_message_obj(Isolate* isolate);
964
965   // Static variables containing common double constants.
966   static ExternalReference address_of_min_int();
967   static ExternalReference address_of_one_half();
968   static ExternalReference address_of_minus_one_half();
969   static ExternalReference address_of_negative_infinity();
970   static ExternalReference address_of_the_hole_nan();
971   static ExternalReference address_of_uint32_bias();
972
973   static ExternalReference math_log_double_function(Isolate* isolate);
974
975   static ExternalReference math_exp_constants(int constant_index);
976   static ExternalReference math_exp_log_table();
977
978   static ExternalReference page_flags(Page* page);
979
980   static ExternalReference ForDeoptEntry(Address entry);
981
982   static ExternalReference cpu_features();
983
984   static ExternalReference debug_is_active_address(Isolate* isolate);
985   static ExternalReference debug_after_break_target_address(Isolate* isolate);
986   static ExternalReference debug_restarter_frame_function_pointer_address(
987       Isolate* isolate);
988
989   static ExternalReference is_profiling_address(Isolate* isolate);
990   static ExternalReference invoke_function_callback(Isolate* isolate);
991   static ExternalReference invoke_accessor_getter_callback(Isolate* isolate);
992
993   static ExternalReference vector_store_virtual_register(Isolate* isolate);
994
995   Address address() const { return reinterpret_cast<Address>(address_); }
996
997   // Used to check if single stepping is enabled in generated code.
998   static ExternalReference debug_step_in_fp_address(Isolate* isolate);
999
1000 #ifndef V8_INTERPRETED_REGEXP
1001   // C functions called from RegExp generated code.
1002
1003   // Function NativeRegExpMacroAssembler::CaseInsensitiveCompareUC16()
1004   static ExternalReference re_case_insensitive_compare_uc16(Isolate* isolate);
1005
1006   // Function RegExpMacroAssembler*::CheckStackGuardState()
1007   static ExternalReference re_check_stack_guard_state(Isolate* isolate);
1008
1009   // Function NativeRegExpMacroAssembler::GrowStack()
1010   static ExternalReference re_grow_stack(Isolate* isolate);
1011
1012   // byte NativeRegExpMacroAssembler::word_character_bitmap
1013   static ExternalReference re_word_character_map();
1014
1015 #endif
1016
1017   // This lets you register a function that rewrites all external references.
1018   // Used by the ARM simulator to catch calls to external references.
1019   static void set_redirector(Isolate* isolate,
1020                              ExternalReferenceRedirector* redirector) {
1021     // We can't stack them.
1022     DCHECK(isolate->external_reference_redirector() == NULL);
1023     isolate->set_external_reference_redirector(
1024         reinterpret_cast<ExternalReferenceRedirectorPointer*>(redirector));
1025   }
1026
1027   static ExternalReference stress_deopt_count(Isolate* isolate);
1028
1029   static ExternalReference fixed_typed_array_base_data_offset();
1030
1031  private:
1032   explicit ExternalReference(void* address)
1033       : address_(address) {}
1034
1035   static void* Redirect(Isolate* isolate,
1036                         Address address_arg,
1037                         Type type = ExternalReference::BUILTIN_CALL) {
1038     ExternalReferenceRedirector* redirector =
1039         reinterpret_cast<ExternalReferenceRedirector*>(
1040             isolate->external_reference_redirector());
1041     void* address = reinterpret_cast<void*>(address_arg);
1042     void* answer = (redirector == NULL) ?
1043                    address :
1044                    (*redirector)(address, type);
1045     return answer;
1046   }
1047
1048   void* address_;
1049 };
1050
1051 bool operator==(ExternalReference, ExternalReference);
1052 bool operator!=(ExternalReference, ExternalReference);
1053
1054 size_t hash_value(ExternalReference);
1055
1056 std::ostream& operator<<(std::ostream&, ExternalReference);
1057
1058
1059 // -----------------------------------------------------------------------------
1060 // Position recording support
1061
1062 struct PositionState {
1063   PositionState() : current_position(RelocInfo::kNoPosition),
1064                     written_position(RelocInfo::kNoPosition),
1065                     current_statement_position(RelocInfo::kNoPosition),
1066                     written_statement_position(RelocInfo::kNoPosition) {}
1067
1068   int current_position;
1069   int written_position;
1070
1071   int current_statement_position;
1072   int written_statement_position;
1073 };
1074
1075
1076 class PositionsRecorder BASE_EMBEDDED {
1077  public:
1078   explicit PositionsRecorder(Assembler* assembler)
1079       : assembler_(assembler) {
1080     jit_handler_data_ = NULL;
1081   }
1082
1083   void AttachJITHandlerData(void* user_data) {
1084     jit_handler_data_ = user_data;
1085   }
1086
1087   void* DetachJITHandlerData() {
1088     void* old_data = jit_handler_data_;
1089     jit_handler_data_ = NULL;
1090     return old_data;
1091   }
1092   // Set current position to pos.
1093   void RecordPosition(int pos);
1094
1095   // Set current statement position to pos.
1096   void RecordStatementPosition(int pos);
1097
1098   // Write recorded positions to relocation information.
1099   bool WriteRecordedPositions();
1100
1101   int current_position() const { return state_.current_position; }
1102
1103   int current_statement_position() const {
1104     return state_.current_statement_position;
1105   }
1106
1107  private:
1108   Assembler* assembler_;
1109   PositionState state_;
1110
1111   // Currently jit_handler_data_ is used to store JITHandler-specific data
1112   // over the lifetime of a PositionsRecorder
1113   void* jit_handler_data_;
1114
1115   DISALLOW_COPY_AND_ASSIGN(PositionsRecorder);
1116 };
1117
1118
1119 // -----------------------------------------------------------------------------
1120 // Utility functions
1121
1122 inline int NumberOfBitsSet(uint32_t x) {
1123   unsigned int num_bits_set;
1124   for (num_bits_set = 0; x; x >>= 1) {
1125     num_bits_set += x & 1;
1126   }
1127   return num_bits_set;
1128 }
1129
1130 bool EvalComparison(Token::Value op, double op1, double op2);
1131
1132 // Computes pow(x, y) with the special cases in the spec for Math.pow.
1133 double power_helper(double x, double y);
1134 double power_double_int(double x, int y);
1135 double power_double_double(double x, double y);
1136
1137 // Helper class for generating code or data associated with the code
1138 // right after a call instruction. As an example this can be used to
1139 // generate safepoint data after calls for crankshaft.
1140 class CallWrapper {
1141  public:
1142   CallWrapper() { }
1143   virtual ~CallWrapper() { }
1144   // Called just before emitting a call. Argument is the size of the generated
1145   // call code.
1146   virtual void BeforeCall(int call_size) const = 0;
1147   // Called just after emitting a call, i.e., at the return site for the call.
1148   virtual void AfterCall() const = 0;
1149 };
1150
1151 class NullCallWrapper : public CallWrapper {
1152  public:
1153   NullCallWrapper() { }
1154   virtual ~NullCallWrapper() { }
1155   virtual void BeforeCall(int call_size) const { }
1156   virtual void AfterCall() const { }
1157 };
1158
1159
1160 // -----------------------------------------------------------------------------
1161 // Constant pool support
1162
1163 class ConstantPoolEntry {
1164  public:
1165   ConstantPoolEntry() {}
1166   ConstantPoolEntry(int position, intptr_t value, bool sharing_ok)
1167       : position_(position),
1168         merged_index_(sharing_ok ? SHARING_ALLOWED : SHARING_PROHIBITED),
1169         value_(value) {}
1170   ConstantPoolEntry(int position, double value)
1171       : position_(position), merged_index_(SHARING_ALLOWED), value64_(value) {}
1172
1173   int position() const { return position_; }
1174   bool sharing_ok() const { return merged_index_ != SHARING_PROHIBITED; }
1175   bool is_merged() const { return merged_index_ >= 0; }
1176   int merged_index(void) const {
1177     DCHECK(is_merged());
1178     return merged_index_;
1179   }
1180   void set_merged_index(int index) {
1181     merged_index_ = index;
1182     DCHECK(is_merged());
1183   }
1184   int offset(void) const {
1185     DCHECK(merged_index_ >= 0);
1186     return merged_index_;
1187   }
1188   void set_offset(int offset) {
1189     DCHECK(offset >= 0);
1190     merged_index_ = offset;
1191   }
1192   intptr_t value() const { return value_; }
1193   uint64_t value64() const { return bit_cast<uint64_t>(value64_); }
1194
1195   enum Type { INTPTR, DOUBLE, NUMBER_OF_TYPES };
1196
1197   static int size(Type type) {
1198     return (type == INTPTR) ? kPointerSize : kDoubleSize;
1199   }
1200
1201   enum Access { REGULAR, OVERFLOWED };
1202
1203  private:
1204   int position_;
1205   int merged_index_;
1206   union {
1207     intptr_t value_;
1208     double value64_;
1209   };
1210   enum { SHARING_PROHIBITED = -2, SHARING_ALLOWED = -1 };
1211 };
1212
1213
1214 // -----------------------------------------------------------------------------
1215 // Embedded constant pool support
1216
1217 class ConstantPoolBuilder BASE_EMBEDDED {
1218  public:
1219   ConstantPoolBuilder(int ptr_reach_bits, int double_reach_bits);
1220
1221   // Add pointer-sized constant to the embedded constant pool
1222   ConstantPoolEntry::Access AddEntry(int position, intptr_t value,
1223                                      bool sharing_ok) {
1224     ConstantPoolEntry entry(position, value, sharing_ok);
1225     return AddEntry(entry, ConstantPoolEntry::INTPTR);
1226   }
1227
1228   // Add double constant to the embedded constant pool
1229   ConstantPoolEntry::Access AddEntry(int position, double value) {
1230     ConstantPoolEntry entry(position, value);
1231     return AddEntry(entry, ConstantPoolEntry::DOUBLE);
1232   }
1233
1234   // Previews the access type required for the next new entry to be added.
1235   ConstantPoolEntry::Access NextAccess(ConstantPoolEntry::Type type) const;
1236
1237   bool IsEmpty() {
1238     return info_[ConstantPoolEntry::INTPTR].entries.empty() &&
1239            info_[ConstantPoolEntry::INTPTR].shared_entries.empty() &&
1240            info_[ConstantPoolEntry::DOUBLE].entries.empty() &&
1241            info_[ConstantPoolEntry::DOUBLE].shared_entries.empty();
1242   }
1243
1244   // Emit the constant pool.  Invoke only after all entries have been
1245   // added and all instructions have been emitted.
1246   // Returns position of the emitted pool (zero implies no constant pool).
1247   int Emit(Assembler* assm);
1248
1249   // Returns the label associated with the start of the constant pool.
1250   // Linking to this label in the function prologue may provide an
1251   // efficient means of constant pool pointer register initialization
1252   // on some architectures.
1253   inline Label* EmittedPosition() { return &emitted_label_; }
1254
1255  private:
1256   ConstantPoolEntry::Access AddEntry(ConstantPoolEntry& entry,
1257                                      ConstantPoolEntry::Type type);
1258   void EmitSharedEntries(Assembler* assm, ConstantPoolEntry::Type type);
1259   void EmitGroup(Assembler* assm, ConstantPoolEntry::Access access,
1260                  ConstantPoolEntry::Type type);
1261
1262   struct PerTypeEntryInfo {
1263     PerTypeEntryInfo() : regular_count(0), overflow_start(-1) {}
1264     bool overflow() const {
1265       return (overflow_start >= 0 &&
1266               overflow_start < static_cast<int>(entries.size()));
1267     }
1268     int regular_reach_bits;
1269     int regular_count;
1270     int overflow_start;
1271     std::vector<ConstantPoolEntry> entries;
1272     std::vector<ConstantPoolEntry> shared_entries;
1273   };
1274
1275   Label emitted_label_;  // Records pc_offset of emitted pool
1276   PerTypeEntryInfo info_[ConstantPoolEntry::NUMBER_OF_TYPES];
1277 };
1278
1279
1280 } }  // namespace v8::internal
1281
1282 #endif  // V8_ASSEMBLER_H_