1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright (c) 1994-2006 Sun Microsystems Inc.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// All Rights Reserved.
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Redistributions of source code must retain the above copyright notice,
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// this list of conditions and the following disclaimer.
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Redistribution in binary form must reproduce the above copyright
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer in the
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// documentation and/or other materials provided with the distribution.
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Neither the name of Sun Microsystems or the names of contributors may
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// be used to endorse or promote products derived from this software without
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// specific prior written permission.
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The original source code covered by the above license above has been
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modified significantly by Google Inc.
333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_ASSEMBLER_H_
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_ASSEMBLER_H_
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/allocation.h"
39f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/builtins/builtins.h"
40f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/deoptimize-reason.h"
41c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "src/globals.h"
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/isolate.h"
4362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/label.h"
443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#include "src/log.h"
4513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include "src/register-configuration.h"
46958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/runtime/runtime.h"
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Forward declarations.
513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass ApiFunction;
523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Forward declarations.
56c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochclass SourcePosition;
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass StatsCounter;
58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// -----------------------------------------------------------------------------
6044f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Platform independent assembler base class.
6144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochenum class CodeObjectRequired { kNo, kYes };
63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
6544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass AssemblerBase: public Malloced {
6644f0eee88ff00398ff7f715fab053374d808c90dSteve Block public:
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AssemblerBase(Isolate* isolate, void* buffer, int buffer_size);
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual ~AssemblerBase();
6944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
7044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate() const { return isolate_; }
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int jit_cookie() const { return jit_cookie_; }
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool emit_debug_code() const { return emit_debug_code_; }
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_emit_debug_code(bool value) { emit_debug_code_ = value; }
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool serializer_enabled() const { return serializer_enabled_; }
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void enable_serializer() { serializer_enabled_ = true; }
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool predictable_code_size() const { return predictable_code_size_; }
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_predictable_code_size(bool value) { predictable_code_size_ = value; }
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint64_t enabled_cpu_features() const { return enabled_cpu_features_; }
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_enabled_cpu_features(uint64_t features) {
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    enabled_cpu_features_ = features;
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
86f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Features are usually enabled by CpuFeatureScope, which also asserts that
87f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // the features are supported before they are enabled.
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsEnabled(CpuFeature f) {
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return (enabled_cpu_features_ & (static_cast<uint64_t>(1) << f)) != 0;
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
91f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void EnableCpuFeature(CpuFeature f) {
92f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    enabled_cpu_features_ |= (static_cast<uint64_t>(1) << f);
93f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
9444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool is_constant_pool_available() const {
96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (FLAG_enable_embedded_constant_pool) {
97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return constant_pool_available_;
98958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Embedded constant pool not supported on this architecture.
100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      UNREACHABLE();
101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return false;
102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
105db1b4389239a7132c9cde0915dbd3f775dc1027aBen Murdoch  // Overwrite a host NaN with a quiet target NaN.  Used by mksnapshot for
106db1b4389239a7132c9cde0915dbd3f775dc1027aBen Murdoch  // cross-snapshotting.
107db1b4389239a7132c9cde0915dbd3f775dc1027aBen Murdoch  static void QuietNaN(HeapObject* nan) { }
108db1b4389239a7132c9cde0915dbd3f775dc1027aBen Murdoch
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int pc_offset() const { return static_cast<int>(pc_ - buffer_); }
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // This function is called when code generation is aborted, so that
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // the assembler could clean up internal data structures.
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual void AbortedCodeGeneration() { }
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Debugging
116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Print();
117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kMinimalBufferSize = 4*KB;
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static void FlushICache(Isolate* isolate, void* start, size_t size);
121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The buffer into which code and relocation info are generated. It could
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // either be owned by the assembler or be provided externally.
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  byte* buffer_;
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int buffer_size_;
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool own_buffer_;
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_constant_pool_available(bool available) {
130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (FLAG_enable_embedded_constant_pool) {
131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      constant_pool_available_ = available;
132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Embedded constant pool not supported on this architecture.
134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      UNREACHABLE();
135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The program counter, which points into the buffer above and moves forward.
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  byte* pc_;
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
14144f0eee88ff00398ff7f715fab053374d808c90dSteve Block private:
14244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate_;
143053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  int jit_cookie_;
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint64_t enabled_cpu_features_;
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool emit_debug_code_;
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool predictable_code_size_;
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool serializer_enabled_;
148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Indicates whether the constant pool can be accessed, which is only possible
150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // if the pp register points to the current code object's constant pool.
151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool constant_pool_available_;
152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Constant pool.
154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  friend class FrameAndConstantPoolScope;
155958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  friend class ConstantPoolUnavailableScope;
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Avoids emitting debug code during the lifetime of this scope object.
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass DontEmitDebugCodeScope BASE_EMBEDDED {
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit DontEmitDebugCodeScope(AssemblerBase* assembler)
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : assembler_(assembler), old_value_(assembler->emit_debug_code()) {
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assembler_->set_emit_debug_code(false);
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ~DontEmitDebugCodeScope() {
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assembler_->set_emit_debug_code(old_value_);
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AssemblerBase* assembler_;
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool old_value_;
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Avoids using instructions that vary in size in unpredictable ways between the
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// snapshot and the running VM.
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass PredictableCodeSizeScope {
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  explicit PredictableCodeSizeScope(AssemblerBase* assembler);
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PredictableCodeSizeScope(AssemblerBase* assembler, int expected_size);
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ~PredictableCodeSizeScope();
182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void ExpectSize(int expected_size) { expected_size_ = expected_size; }
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AssemblerBase* assembler_;
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int expected_size_;
187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int start_offset_;
188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool old_value_;
189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Enable a specified feature within a scope.
193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CpuFeatureScope BASE_EMBEDDED {
194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
195f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  enum CheckPolicy {
196f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    kCheckSupported,
197f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    kDontCheckSupported,
198f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  };
199f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
201f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  CpuFeatureScope(AssemblerBase* assembler, CpuFeature f,
202f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                  CheckPolicy check = kCheckSupported);
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ~CpuFeatureScope();
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AssemblerBase* assembler_;
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint64_t old_enabled_;
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#else
209f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  CpuFeatureScope(AssemblerBase* assembler, CpuFeature f,
210f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                  CheckPolicy check = kCheckSupported) {}
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// CpuFeatures keeps track of which features are supported by the target CPU.
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Supported features must be enabled by a CpuFeatureScope before use.
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Example:
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//   if (assembler->IsSupported(SSE3)) {
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//     CpuFeatureScope fscope(assembler, SSE3);
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//     // Generate code containing SSE3 instructions.
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//   } else {
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//     // Generate alternative code.
223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//   }
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CpuFeatures : public AllStatic {
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void Probe(bool cross_compile) {
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    STATIC_ASSERT(NUMBER_OF_CPU_FEATURES <= kBitsPerInt);
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (initialized_) return;
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    initialized_ = true;
230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ProbeImpl(cross_compile);
231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static unsigned SupportedFeatures() {
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Probe(false);
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return supported_;
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool IsSupported(CpuFeature f) {
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return (supported_ & (1u << f)) != 0;
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline bool SupportsCrankshaft();
243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
244f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static inline bool SupportsSimd128();
245f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
246109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  static inline unsigned icache_line_size() {
247109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DCHECK(icache_line_size_ != 0);
248109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return icache_line_size_;
249109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
250109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
251109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  static inline unsigned dcache_line_size() {
252109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DCHECK(dcache_line_size_ != 0);
253109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return dcache_line_size_;
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void PrintTarget();
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void PrintFeatures();
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  friend class ExternalReference;
261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  friend class AssemblerBase;
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Flush instruction cache.
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void FlushICache(void* start, size_t size);
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Platform-dependent implementation.
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void ProbeImpl(bool cross_compile);
267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static unsigned supported_;
269109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  static unsigned icache_line_size_;
270109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  static unsigned dcache_line_size_;
271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool initialized_;
272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DISALLOW_COPY_AND_ASSIGN(CpuFeatures);
27344f0eee88ff00398ff7f715fab053374d808c90dSteve Block};
27444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
275b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochenum SaveFPRegsMode { kDontSaveFPRegs, kSaveFPRegs };
2773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochenum ArgvMode { kArgvOnStack, kArgvInRegister };
279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Specifies whether to perform icache flush operations on RelocInfo updates.
281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// If FLUSH_ICACHE_IF_NEEDED, the icache will always be flushed if an
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// instruction was modified. If SKIP_ICACHE_FLUSH the flush will always be
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// skipped (only use this if you will flush the icache manually before it is
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// executed).
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum ICacheFlushMode { FLUSH_ICACHE_IF_NEEDED, SKIP_ICACHE_FLUSH };
2863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// -----------------------------------------------------------------------------
288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Relocation information
289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Relocation information consists of the address (pc) of the datum
292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// to which the relocation information applies, the relocation mode
293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (rmode), and an optional data field. The relocation mode may be
294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "descriptive" and not indicate a need for relocation, but simply
295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// describe a property of the datum. Such rmodes are useful for GC
296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// and nice disassembly output.
297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass RelocInfo {
299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
300e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // This string is used to add padding comments to the reloc info in cases
301e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // where we are not sure to have enough space for patching in during
302e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // lazy deoptimization. This is the case if we have indirect calls for which
303e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // we do not normally record relocation info.
30469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  static const char* const kFillerCommentString;
305e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The minimum size of a comment is equal to two bytes for the extra tagged
307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // pc and kPointerSize for the actual pointer to the comment.
308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static const int kMinRelocCommentSize = 2 + kPointerSize;
309e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
310e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // The maximum size for a call instruction including pc-jump.
311e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  static const int kMaxCallSize = 6;
312e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
31344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // The maximum pc delta that will use the short encoding.
31444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static const int kMaxSmallPCDelta;
31544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  enum Mode {
317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Please note the order is important (see IsCodeTarget, IsGCRelocMode).
318257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    CODE_TARGET,  // Code target which is not any of the above.
319257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    CODE_TARGET_WITH_ID,
320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    EMBEDDED_OBJECT,
3213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // To relocate pointers into the wasm memory embedded in wasm code
3223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    WASM_MEMORY_REFERENCE,
32313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    WASM_GLOBAL_REFERENCE,
324bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    WASM_MEMORY_SIZE_REFERENCE,
32562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    WASM_FUNCTION_TABLE_SIZE_REFERENCE,
32662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    WASM_PROTECTED_INSTRUCTION_LANDING,
327bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    CELL,
328b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Everything after runtime_entry (inclusive) is not GC'ed.
330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    RUNTIME_ENTRY,
331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    COMMENT,
332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Additional code inserted for debug break slot.
334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DEBUG_BREAK_SLOT_AT_POSITION,
335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DEBUG_BREAK_SLOT_AT_RETURN,
336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DEBUG_BREAK_SLOT_AT_CALL,
3373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    DEBUG_BREAK_SLOT_AT_TAIL_CALL,
338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    EXTERNAL_REFERENCE,  // The address of an external C++ function.
340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    INTERNAL_REFERENCE,  // An address inside the same function.
341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Encoded internal reference, used only on MIPS, MIPS64 and PPC.
343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    INTERNAL_REFERENCE_ENCODED,
344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Marks constant and veneer pools. Only used on ARM and ARM64.
346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // They use a custom noncompact encoding.
347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CONST_POOL,
348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VENEER_POOL,
349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
350c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    DEOPT_SCRIPT_OFFSET,
351c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    DEOPT_INLINING_ID,  // Deoptimization source position.
352c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    DEOPT_REASON,       // Deoptimization reason index.
353c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    DEOPT_ID,           // Deoptimization inlining id.
354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // This is not an actual reloc mode, but used to encode a long pc jump that
356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // cannot be encoded as part of another record.
357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PC_JUMP,
358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Pseudo-types
360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    NUMBER_OF_MODES,
361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    NONE32,             // never recorded 32-bit value
362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    NONE64,             // never recorded 64-bit value
363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CODE_AGE_SEQUENCE,  // Not stored in RelocInfo array, used explictly by
364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        // code aging.
365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FIRST_REAL_RELOC_MODE = CODE_TARGET,
367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LAST_REAL_RELOC_MODE = VENEER_POOL,
36862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    LAST_CODE_ENUM = CODE_TARGET_WITH_ID,
36962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    LAST_GCED_ENUM = WASM_FUNCTION_TABLE_SIZE_REFERENCE,
3703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    FIRST_SHAREABLE_RELOC_MODE = CELL,
371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  STATIC_ASSERT(NUMBER_OF_MODES <= kBitsPerInt);
3743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  explicit RelocInfo(Isolate* isolate) : isolate_(isolate) {
376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_NOT_NULL(isolate);
377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RelocInfo(Isolate* isolate, byte* pc, Mode rmode, intptr_t data, Code* host)
380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : isolate_(isolate), pc_(pc), rmode_(rmode), data_(data), host_(host) {
381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_NOT_NULL(isolate);
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline bool IsRealRelocMode(Mode mode) {
38513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    return mode >= FIRST_REAL_RELOC_MODE && mode <= LAST_REAL_RELOC_MODE;
386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline bool IsCodeTarget(Mode mode) {
388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return mode <= LAST_CODE_ENUM;
389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
3903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static inline bool IsEmbeddedObject(Mode mode) {
3913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return mode == EMBEDDED_OBJECT;
3923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static inline bool IsCell(Mode mode) { return mode == CELL; }
394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline bool IsRuntimeEntry(Mode mode) {
395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return mode == RUNTIME_ENTRY;
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Is the relocation mode affected by GC?
398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline bool IsGCRelocMode(Mode mode) {
399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return mode <= LAST_GCED_ENUM;
400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline bool IsComment(Mode mode) {
402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return mode == COMMENT;
403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline bool IsConstPool(Mode mode) {
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return mode == CONST_POOL;
406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline bool IsVeneerPool(Mode mode) {
408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return mode == VENEER_POOL;
409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
410f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static inline bool IsDeoptPosition(Mode mode) {
411c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return mode == DEOPT_SCRIPT_OFFSET || mode == DEOPT_INLINING_ID;
412f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static inline bool IsDeoptReason(Mode mode) {
414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return mode == DEOPT_REASON;
415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
416bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  static inline bool IsDeoptId(Mode mode) {
417bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    return mode == DEOPT_ID;
418bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline bool IsExternalReference(Mode mode) {
420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return mode == EXTERNAL_REFERENCE;
421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline bool IsInternalReference(Mode mode) {
423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return mode == INTERNAL_REFERENCE;
424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static inline bool IsInternalReferenceEncoded(Mode mode) {
426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return mode == INTERNAL_REFERENCE_ENCODED;
427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
4287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static inline bool IsDebugBreakSlot(Mode mode) {
429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return IsDebugBreakSlotAtPosition(mode) || IsDebugBreakSlotAtReturn(mode) ||
4303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch           IsDebugBreakSlotAtCall(mode) || IsDebugBreakSlotAtTailCall(mode);
431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static inline bool IsDebugBreakSlotAtPosition(Mode mode) {
433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return mode == DEBUG_BREAK_SLOT_AT_POSITION;
434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static inline bool IsDebugBreakSlotAtReturn(Mode mode) {
436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return mode == DEBUG_BREAK_SLOT_AT_RETURN;
437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static inline bool IsDebugBreakSlotAtCall(Mode mode) {
439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return mode == DEBUG_BREAK_SLOT_AT_CALL;
440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
4413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static inline bool IsDebugBreakSlotAtTailCall(Mode mode) {
4423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return mode == DEBUG_BREAK_SLOT_AT_TAIL_CALL;
4433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline bool IsNone(Mode mode) {
445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return mode == NONE32 || mode == NONE64;
446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline bool IsCodeAgeSequence(Mode mode) {
448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return mode == CODE_AGE_SEQUENCE;
449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static inline bool IsWasmMemoryReference(Mode mode) {
4513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return mode == WASM_MEMORY_REFERENCE;
4523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
453bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  static inline bool IsWasmMemorySizeReference(Mode mode) {
454bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    return mode == WASM_MEMORY_SIZE_REFERENCE;
455bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
45613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  static inline bool IsWasmGlobalReference(Mode mode) {
45713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    return mode == WASM_GLOBAL_REFERENCE;
45813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
45962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  static inline bool IsWasmFunctionTableSizeReference(Mode mode) {
46062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return mode == WASM_FUNCTION_TABLE_SIZE_REFERENCE;
46162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
46262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  static inline bool IsWasmReference(Mode mode) {
46362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return mode == WASM_MEMORY_REFERENCE || mode == WASM_GLOBAL_REFERENCE ||
46462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch           mode == WASM_MEMORY_SIZE_REFERENCE ||
46562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch           mode == WASM_FUNCTION_TABLE_SIZE_REFERENCE;
46662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
46762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  static inline bool IsWasmSizeReference(Mode mode) {
46862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return mode == WASM_MEMORY_SIZE_REFERENCE ||
46962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch           mode == WASM_FUNCTION_TABLE_SIZE_REFERENCE;
47062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
47162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  static inline bool IsWasmPtrReference(Mode mode) {
47262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return mode == WASM_MEMORY_REFERENCE || mode == WASM_GLOBAL_REFERENCE;
47362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
47462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  static inline bool IsWasmProtectedLanding(Mode mode) {
47562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return mode == WASM_PROTECTED_INSTRUCTION_LANDING;
47662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
47762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static inline int ModeMask(Mode mode) { return 1 << mode; }
479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Accessors
481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Isolate* isolate() const { return isolate_; }
4820d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  byte* pc() const { return pc_; }
483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void set_pc(byte* pc) { pc_ = pc; }
484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Mode rmode() const {  return rmode_; }
4850d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  intptr_t data() const { return data_; }
4863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Code* host() const { return host_; }
487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_host(Code* host) { host_ = host; }
488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Apply a relocation by delta bytes. When the code object is moved, PC
490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // relative addresses have to be updated as well as absolute addresses
491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // inside the code (internal references).
492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Do not forget to flush the icache afterwards!
493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  INLINE(void apply(intptr_t delta));
494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
495f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Is the pointer this relocation info refers to coded like a plain pointer
4963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // or is it strange in some way (e.g. relative or patched into a series of
497f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // instructions).
498f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  bool IsCodedSpecially();
499f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If true, the pointer this relocation info refers to is an entry in the
501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // constant pool, otherwise the pointer is embedded in the instruction stream.
502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsInConstantPool();
503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
504bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Address wasm_memory_reference();
50513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Address wasm_global_reference();
50662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  uint32_t wasm_function_table_size_reference();
507bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  uint32_t wasm_memory_size_reference();
508bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  void update_wasm_memory_reference(
50962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Address old_base, Address new_base,
51062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
51162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void update_wasm_memory_size(
51262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      uint32_t old_size, uint32_t new_size,
513f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
51413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void update_wasm_global_reference(
51513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Address old_base, Address new_base,
516f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
51762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void update_wasm_function_table_size_reference(
51862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      uint32_t old_base, uint32_t new_base,
51962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
520f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void set_target_address(
521f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Address target,
522f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      WriteBarrierMode write_barrier_mode = UPDATE_WRITE_BARRIER,
523f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
524bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // this relocation applies to;
526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // can only be called if IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)
527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  INLINE(Address target_address());
528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  INLINE(Object* target_object());
5293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  INLINE(Handle<Object> target_object_handle(Assembler* origin));
53013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  INLINE(void set_target_object(
53113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Object* target,
53213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      WriteBarrierMode write_barrier_mode = UPDATE_WRITE_BARRIER,
53313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED));
534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  INLINE(Address target_runtime_entry(Assembler* origin));
53513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  INLINE(void set_target_runtime_entry(
53613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Address target,
53713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      WriteBarrierMode write_barrier_mode = UPDATE_WRITE_BARRIER,
53813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED));
539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  INLINE(Cell* target_cell());
540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  INLINE(Handle<Cell> target_cell_handle());
54113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  INLINE(void set_target_cell(
54213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Cell* cell, WriteBarrierMode write_barrier_mode = UPDATE_WRITE_BARRIER,
54313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED));
544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  INLINE(Handle<Object> code_age_stub_handle(Assembler* origin));
545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  INLINE(Code* code_age_stub());
54613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  INLINE(void set_code_age_stub(
54713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Code* stub, ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED));
548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Returns the address of the constant pool entry where the target address
550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // is held.  This should only be called if IsInConstantPool returns true.
551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  INLINE(Address constant_pool_entry_address());
552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
553f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Read the address of the word containing the target_address in an
554f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // instruction stream.  What this means exactly is architecture-independent.
555f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // The only architecture-independent user of this function is the serializer.
556f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // The serializer uses it to find out how many raw bytes of instruction to
557f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // output before the next target.  Architecture-independent code shouldn't
558f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // dereference the pointer it gets back from this.
559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  INLINE(Address target_address_address());
560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
561f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // This indicates how much space a target takes up when deserializing a code
562f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // stream.  For most architectures this is just the size of a pointer.  For
563f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // an instruction like movw/movt where the target bits are mixed into the
564f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // instruction bits the size of the target will be zero, indicating that the
565f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // serializer should not step forwards in memory after a target is resolved
566f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // and written.  In this case the target_address_address function above
567f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // should return the end of the instructions to be patched, allowing the
568f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // deserializer to deserialize the instructions as raw bytes and put them in
569f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // place, ready to be patched with the target.
570f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  INLINE(int target_address_size());
571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Read the reference in the instruction this relocation
573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // applies to; can only be called if rmode_ is EXTERNAL_REFERENCE.
574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  INLINE(Address target_external_reference());
575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Read the reference in the instruction this relocation
577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // applies to; can only be called if rmode_ is INTERNAL_REFERENCE.
578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  INLINE(Address target_internal_reference());
579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Return the reference address this relocation applies to;
581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // can only be called if rmode_ is INTERNAL_REFERENCE.
582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  INLINE(Address target_internal_reference_address());
583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Read/modify the address of a call instruction. This is used to relocate
585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the break points where straight-line code is patched with a call
586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // instruction.
587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  INLINE(Address debug_call_address());
588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  INLINE(void set_debug_call_address(Address target));
589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Wipe out a relocation to a fixed value, used for making snapshots
591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // reproducible.
592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  INLINE(void WipeOut());
593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
59444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  template<typename StaticVisitor> inline void Visit(Heap* heap);
595bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
596bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  template <typename ObjectVisitor>
597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void Visit(Isolate* isolate, ObjectVisitor* v);
598f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
5997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Check whether this debug break slot has been patched with a call to the
6007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // debugger.
601109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bool IsPatchedDebugBreakSlotSequence();
6027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Check whether the given code contains relocation information that
605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // either is position-relative or movable by the garbage collector.
606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool RequiresRelocation(const CodeDesc& desc);
607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DISASSEMBLER
610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Printing
611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const char* RelocModeName(Mode rmode);
612958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void Print(Isolate* isolate, std::ostream& os);  // NOLINT
613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // ENABLE_DISASSEMBLER
614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP
615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Verify(Isolate* isolate);
616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kCodeTargetMask = (1 << (LAST_CODE_ENUM + 1)) - 1;
619f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static const int kDataMask = (1 << CODE_TARGET_WITH_ID) | (1 << COMMENT);
620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static const int kDebugBreakSlotMask = 1 << DEBUG_BREAK_SLOT_AT_POSITION |
621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                         1 << DEBUG_BREAK_SLOT_AT_RETURN |
622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                         1 << DEBUG_BREAK_SLOT_AT_CALL;
623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static const int kApplyMask;  // Modes affected by apply.  Depends on arch.
624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
62613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void unchecked_update_wasm_memory_reference(Address address,
62713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                              ICacheFlushMode flush_mode);
62862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void unchecked_update_wasm_size(uint32_t size, ICacheFlushMode flush_mode);
62913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Isolate* isolate_;
631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // On ARM, note that pc_ is the address of the constant pool entry
632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // to be relocated and not the address of the instruction
633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // referencing the constant pool entry (except when rmode_ ==
634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // comment).
635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  byte* pc_;
636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Mode rmode_;
637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  intptr_t data_;
6383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Code* host_;
639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  friend class RelocIterator;
640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// RelocInfoWriter serializes a stream of relocation info. It writes towards
644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// lower addresses.
645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass RelocInfoWriter BASE_EMBEDDED {
646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
647f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  RelocInfoWriter() : pos_(NULL), last_pc_(NULL), last_id_(0) {}
648f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  RelocInfoWriter(byte* pos, byte* pc) : pos_(pos), last_pc_(pc), last_id_(0) {}
649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  byte* pos() const { return pos_; }
651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  byte* last_pc() const { return last_pc_; }
652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Write(const RelocInfo* rinfo);
654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Update the state of the stream after reloc info buffer
656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // and/or code is moved while the stream is active.
657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Reposition(byte* pos, byte* pc) {
658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    pos_ = pos;
659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    last_pc_ = pc;
660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Max size (bytes) of a written RelocInfo. Longest encoding is
663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // ExtraTag, VariableLengthPCJump, ExtraTag, pc_delta, data_delta.
664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // On ia32 and arm this is 1 + 4 + 1 + 1 + 4 = 11.
665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // On x64 this is 1 + 4 + 1 + 1 + 8 == 15;
666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Here we use the maximum of the two.
667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static const int kMaxSize = 15;
668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inline uint32_t WriteLongPCJump(uint32_t pc_delta);
671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inline void WriteShortTaggedPC(uint32_t pc_delta, int tag);
673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inline void WriteShortTaggedData(intptr_t data_delta, int tag);
674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inline void WriteMode(RelocInfo::Mode rmode);
676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inline void WriteModeAndPC(uint32_t pc_delta, RelocInfo::Mode rmode);
677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inline void WriteIntData(int data_delta);
678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inline void WriteData(intptr_t data_delta);
679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  byte* pos_;
681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  byte* last_pc_;
682257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  int last_id_;
683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RelocInfo::Mode last_mode_;
684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_COPY_AND_ASSIGN(RelocInfoWriter);
686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A RelocIterator iterates over relocation information.
690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Typical use:
691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//   for (RelocIterator it(code); !it.done(); it.next()) {
693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     // do something with it.rinfo() here
694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//   }
695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A mask can be specified to skip unwanted modes.
697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass RelocIterator: public Malloced {
698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Create a new iterator positioned at
700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the beginning of the reloc info.
701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Relocation information with mode k is included in the
702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // iteration iff bit k of mode_mask is set.
703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  explicit RelocIterator(Code* code, int mode_mask = -1);
704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  explicit RelocIterator(const CodeDesc& desc, int mode_mask = -1);
705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Iteration
7070d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  bool done() const { return done_; }
708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void next();
709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Return pointer valid until next next().
711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  RelocInfo* rinfo() {
712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!done());
713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return &rinfo_;
714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Advance* moves the position before/after reading.
718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // *Read* reads from current byte(s) into rinfo_.
719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // *Get* just reads and returns info on current byte.
720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Advance(int bytes = 1) { pos_ -= bytes; }
721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int AdvanceGetTag();
722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RelocInfo::Mode GetMode();
723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void AdvanceReadLongPCJump();
725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int GetShortDataTypeTag();
727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void ReadShortTaggedPC();
728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void ReadShortTaggedId();
729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void ReadShortTaggedData();
730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void AdvanceReadPC();
732257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void AdvanceReadId();
733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void AdvanceReadInt();
734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void AdvanceReadData();
735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If the given mode is wanted, set it in rinfo_ and return true.
737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Else return false. Used for efficiently skipping unwanted modes.
738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool SetMode(RelocInfo::Mode mode) {
739b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return (mode_mask_ & (1 << mode)) ? (rinfo_.rmode_ = mode, true) : false;
740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  byte* pos_;
743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  byte* end_;
744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  byte* code_age_sequence_;
745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  RelocInfo rinfo_;
746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool done_;
747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int mode_mask_;
748257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  int last_id_;
749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_COPY_AND_ASSIGN(RelocIterator);
750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//------------------------------------------------------------------------------
754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// External function
755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//----------------------------------------------------------------------------
757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass SCTableReference;
758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Debug_Address;
759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// An ExternalReference represents a C++ address used in the generated
762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// code. All references to C++ functions and variables must be encapsulated in
763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// an ExternalReference instance. This is done in order to track the origin of
764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// all external references in the code so that they can be bound to the correct
765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// addresses when deserializing a heap.
766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ExternalReference BASE_EMBEDDED {
767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
7681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Used in the simulator to support different native api calls.
7691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  enum Type {
770e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    // Builtin call.
771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Object* f(v8::internal::Arguments).
7721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    BUILTIN_CALL,  // default
773e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
774109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // Builtin call returning object pair.
775109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // ObjectPair f(v8::internal::Arguments).
776109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    BUILTIN_CALL_PAIR,
777109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
778109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // Builtin call that returns .
779109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // ObjectTriple f(v8::internal::Arguments).
780109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    BUILTIN_CALL_TRIPLE,
781109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
782257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // Builtin that takes float arguments and returns an int.
783257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // int f(double, double).
784257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    BUILTIN_COMPARE_CALL,
785257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
786e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    // Builtin call that returns floating point.
787e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    // double f(double, double).
788257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    BUILTIN_FP_FP_CALL,
789257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
790257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // Builtin call that returns floating point.
791257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // double f(double).
792257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    BUILTIN_FP_CALL,
793257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
794257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // Builtin call that returns floating point.
795257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // double f(double, int).
796257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    BUILTIN_FP_INT_CALL,
797e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
798e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    // Direct call to API function callback.
799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // void f(v8::FunctionCallbackInfo&)
800e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    DIRECT_API_CALL,
801e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Call to function callback via InvokeFunctionCallback.
803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // void f(v8::FunctionCallbackInfo&, v8::FunctionCallback)
804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PROFILING_API_CALL,
805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
806e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    // Direct call to accessor getter callback.
807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // void f(Local<Name> property, PropertyCallbackInfo& info)
808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DIRECT_GETTER_CALL,
809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Call to accessor getter callback via InvokeAccessorGetterCallback.
811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // void f(Local<Name> property, PropertyCallbackInfo& info,
812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    //     AccessorNameGetterCallback callback)
813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PROFILING_GETTER_CALL
8141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  };
8151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void SetUp();
817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  typedef void* ExternalReferenceRedirector(Isolate* isolate, void* original,
819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            Type type);
8201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ExternalReference() : address_(NULL) {}
822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
823f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ExternalReference(Address address, Isolate* isolate);
824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
82544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ExternalReference(ApiFunction* ptr, Type type, Isolate* isolate);
826d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
82744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ExternalReference(Builtins::Name name, Isolate* isolate);
828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
82944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ExternalReference(Runtime::FunctionId id, Isolate* isolate);
830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
83144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ExternalReference(const Runtime::Function* f, Isolate* isolate);
832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  explicit ExternalReference(StatsCounter* counter);
834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
83544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ExternalReference(Isolate::AddressId id, Isolate* isolate);
836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  explicit ExternalReference(const SCTableReference& table_ref);
838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Isolate as an external reference.
840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static ExternalReference isolate_address(Isolate* isolate);
84144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // One-of-a-kind references. These references are not part of a general
843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // pattern. This means that they have to be added to the
844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ExternalReferenceTable in serialize.cc manually.
845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
846109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  static ExternalReference interpreter_dispatch_table_address(Isolate* isolate);
847bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  static ExternalReference interpreter_dispatch_counters(Isolate* isolate);
848109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
8493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static ExternalReference incremental_marking_record_write_function(
8503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Isolate* isolate);
851109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  static ExternalReference incremental_marking_record_write_code_entry_function(
852109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      Isolate* isolate);
8533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static ExternalReference store_buffer_overflow_function(
8543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Isolate* isolate);
85544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static ExternalReference delete_handle_scope_extensions(Isolate* isolate);
856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static ExternalReference get_date_field_function(Isolate* isolate);
8583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static ExternalReference date_cache_stamp(Isolate* isolate);
8593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static ExternalReference get_make_code_young_function(Isolate* isolate);
861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static ExternalReference get_mark_code_as_executed_function(Isolate* isolate);
862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
863b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Deoptimization support.
86444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static ExternalReference new_deoptimizer_function(Isolate* isolate);
86544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static ExternalReference compute_output_frames_function(Isolate* isolate);
866b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
8673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static ExternalReference wasm_f32_trunc(Isolate* isolate);
8683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static ExternalReference wasm_f32_floor(Isolate* isolate);
8693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static ExternalReference wasm_f32_ceil(Isolate* isolate);
8703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static ExternalReference wasm_f32_nearest_int(Isolate* isolate);
8713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static ExternalReference wasm_f64_trunc(Isolate* isolate);
8723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static ExternalReference wasm_f64_floor(Isolate* isolate);
8733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static ExternalReference wasm_f64_ceil(Isolate* isolate);
8743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static ExternalReference wasm_f64_nearest_int(Isolate* isolate);
8753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static ExternalReference wasm_int64_to_float32(Isolate* isolate);
8763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static ExternalReference wasm_uint64_to_float32(Isolate* isolate);
8773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static ExternalReference wasm_int64_to_float64(Isolate* isolate);
8783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static ExternalReference wasm_uint64_to_float64(Isolate* isolate);
8793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static ExternalReference wasm_float32_to_int64(Isolate* isolate);
8803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static ExternalReference wasm_float32_to_uint64(Isolate* isolate);
8813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static ExternalReference wasm_float64_to_int64(Isolate* isolate);
8823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static ExternalReference wasm_float64_to_uint64(Isolate* isolate);
8833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static ExternalReference wasm_int64_div(Isolate* isolate);
8843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static ExternalReference wasm_int64_mod(Isolate* isolate);
8853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static ExternalReference wasm_uint64_div(Isolate* isolate);
8863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static ExternalReference wasm_uint64_mod(Isolate* isolate);
887bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  static ExternalReference wasm_word32_ctz(Isolate* isolate);
888bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  static ExternalReference wasm_word64_ctz(Isolate* isolate);
889bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  static ExternalReference wasm_word32_popcnt(Isolate* isolate);
890bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  static ExternalReference wasm_word64_popcnt(Isolate* isolate);
891f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static ExternalReference wasm_float64_pow(Isolate* isolate);
8923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
8933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static ExternalReference f64_acos_wrapper_function(Isolate* isolate);
8943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static ExternalReference f64_asin_wrapper_function(Isolate* isolate);
8953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static ExternalReference f64_mod_wrapper_function(Isolate* isolate);
896109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
89762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Trap callback function for cctest/wasm/wasm-run-utils.h
89862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  static ExternalReference wasm_call_trap_callback_for_testing(
89962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Isolate* isolate);
90062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Log support.
902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static ExternalReference log_enter_external_function(Isolate* isolate);
903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static ExternalReference log_leave_external_function(Isolate* isolate);
904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
9053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Static variable Heap::roots_array_start()
9063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static ExternalReference roots_array_start(Isolate* isolate);
907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Static variable Heap::allocation_sites_list_address()
909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static ExternalReference allocation_sites_list_address(Isolate* isolate);
910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Static variable StackGuard::address_of_jslimit()
912c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  V8_EXPORT_PRIVATE static ExternalReference address_of_stack_limit(
913c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      Isolate* isolate);
914d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
915d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Static variable StackGuard::address_of_real_jslimit()
91644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static ExternalReference address_of_real_stack_limit(Isolate* isolate);
917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Static variable RegExpStack::limit_address()
91944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static ExternalReference address_of_regexp_stack_limit(Isolate* isolate);
920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
921e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Static variables for RegExp.
92244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static ExternalReference address_of_static_offsets_vector(Isolate* isolate);
92344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static ExternalReference address_of_regexp_stack_memory_address(
92444f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Isolate* isolate);
92544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static ExternalReference address_of_regexp_stack_memory_size(
92644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Isolate* isolate);
927e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
9283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Write barrier.
9293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static ExternalReference store_buffer_top(Isolate* isolate);
930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Used for fast allocation in generated code.
93244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static ExternalReference new_space_allocation_top_address(Isolate* isolate);
93344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static ExternalReference new_space_allocation_limit_address(Isolate* isolate);
934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static ExternalReference old_space_allocation_top_address(Isolate* isolate);
935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static ExternalReference old_space_allocation_limit_address(Isolate* isolate);
936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static ExternalReference mod_two_doubles_operation(Isolate* isolate);
93844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static ExternalReference power_double_double_function(Isolate* isolate);
939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static ExternalReference handle_scope_next_address(Isolate* isolate);
941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static ExternalReference handle_scope_limit_address(Isolate* isolate);
942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static ExternalReference handle_scope_level_address(Isolate* isolate);
943d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
94444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static ExternalReference scheduled_exception_address(Isolate* isolate);
945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static ExternalReference address_of_pending_message_obj(Isolate* isolate);
946d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
947b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Static variables containing common double constants.
948b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static ExternalReference address_of_min_int();
949b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static ExternalReference address_of_one_half();
950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static ExternalReference address_of_minus_one_half();
951b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static ExternalReference address_of_negative_infinity();
9523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static ExternalReference address_of_the_hole_nan();
953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static ExternalReference address_of_uint32_bias();
954b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
955f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Static variables containing simd constants.
956f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static ExternalReference address_of_float_abs_constant();
957f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static ExternalReference address_of_float_neg_constant();
958f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static ExternalReference address_of_double_abs_constant();
959f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static ExternalReference address_of_double_neg_constant();
960f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
96113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // IEEE 754 functions.
962f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static ExternalReference ieee754_acos_function(Isolate* isolate);
963f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static ExternalReference ieee754_acosh_function(Isolate* isolate);
964f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static ExternalReference ieee754_asin_function(Isolate* isolate);
965f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static ExternalReference ieee754_asinh_function(Isolate* isolate);
96613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  static ExternalReference ieee754_atan_function(Isolate* isolate);
96713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  static ExternalReference ieee754_atanh_function(Isolate* isolate);
968f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static ExternalReference ieee754_atan2_function(Isolate* isolate);
96913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  static ExternalReference ieee754_cbrt_function(Isolate* isolate);
97013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  static ExternalReference ieee754_cos_function(Isolate* isolate);
971f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static ExternalReference ieee754_cosh_function(Isolate* isolate);
97213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  static ExternalReference ieee754_exp_function(Isolate* isolate);
97313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  static ExternalReference ieee754_expm1_function(Isolate* isolate);
97413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  static ExternalReference ieee754_log_function(Isolate* isolate);
97513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  static ExternalReference ieee754_log1p_function(Isolate* isolate);
97613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  static ExternalReference ieee754_log10_function(Isolate* isolate);
97713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  static ExternalReference ieee754_log2_function(Isolate* isolate);
97813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  static ExternalReference ieee754_sin_function(Isolate* isolate);
979f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static ExternalReference ieee754_sinh_function(Isolate* isolate);
98013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  static ExternalReference ieee754_tan_function(Isolate* isolate);
981f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static ExternalReference ieee754_tanh_function(Isolate* isolate);
982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
98362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  static ExternalReference libc_memchr_function(Isolate* isolate);
98462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static ExternalReference page_flags(Page* page);
986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static ExternalReference ForDeoptEntry(Address entry);
988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static ExternalReference cpu_features();
990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
9913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static ExternalReference is_tail_call_elimination_enabled_address(
9923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Isolate* isolate);
9933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static ExternalReference debug_is_active_address(Isolate* isolate);
99562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  static ExternalReference debug_hook_on_function_call_address(
99662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Isolate* isolate);
997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static ExternalReference debug_after_break_target_address(Isolate* isolate);
998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static ExternalReference is_profiling_address(Isolate* isolate);
1000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static ExternalReference invoke_function_callback(Isolate* isolate);
1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static ExternalReference invoke_accessor_getter_callback(Isolate* isolate);
1002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
100362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  static ExternalReference promise_hook_or_debug_is_active_address(
100462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Isolate* isolate);
100562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
1006c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  V8_EXPORT_PRIVATE static ExternalReference runtime_function_table_address(
1007c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      Isolate* isolate);
1008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Address address() const { return reinterpret_cast<Address>(address_); }
1010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
101113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // Used to read out the last step action of the debugger.
101213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  static ExternalReference debug_last_step_action_address(Isolate* isolate);
101313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
101413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // Used to check for suspended generator, used for stepping across await call.
101513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  static ExternalReference debug_suspended_generator_address(Isolate* isolate);
1016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
101762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Used to store the frame pointer to drop to when restarting a frame.
101862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  static ExternalReference debug_restart_fp_address(Isolate* isolate);
101962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
10206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifndef V8_INTERPRETED_REGEXP
1021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // C functions called from RegExp generated code.
1022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Function NativeRegExpMacroAssembler::CaseInsensitiveCompareUC16()
102444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static ExternalReference re_case_insensitive_compare_uc16(Isolate* isolate);
1025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Function RegExpMacroAssembler*::CheckStackGuardState()
102744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static ExternalReference re_check_stack_guard_state(Isolate* isolate);
1028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Function NativeRegExpMacroAssembler::GrowStack()
103044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static ExternalReference re_grow_stack(Isolate* isolate);
1031e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
1032e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // byte NativeRegExpMacroAssembler::word_character_bitmap
1033e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  static ExternalReference re_word_character_map();
1034e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
1035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
1036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // This lets you register a function that rewrites all external references.
1038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Used by the ARM simulator to catch calls to external references.
1039257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static void set_redirector(Isolate* isolate,
1040257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                             ExternalReferenceRedirector* redirector) {
104144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // We can't stack them.
1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(isolate->external_reference_redirector() == NULL);
1043257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    isolate->set_external_reference_redirector(
104444f0eee88ff00398ff7f715fab053374d808c90dSteve Block        reinterpret_cast<ExternalReferenceRedirectorPointer*>(redirector));
1045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static ExternalReference stress_deopt_count(Isolate* isolate);
1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static ExternalReference fixed_typed_array_base_data_offset();
1050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
1052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  explicit ExternalReference(void* address)
1053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      : address_(address) {}
1054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
105544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static void* Redirect(Isolate* isolate,
105644f0eee88ff00398ff7f715fab053374d808c90dSteve Block                        Address address_arg,
10571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block                        Type type = ExternalReference::BUILTIN_CALL) {
105844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ExternalReferenceRedirector* redirector =
105944f0eee88ff00398ff7f715fab053374d808c90dSteve Block        reinterpret_cast<ExternalReferenceRedirector*>(
106044f0eee88ff00398ff7f715fab053374d808c90dSteve Block            isolate->external_reference_redirector());
1061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    void* address = reinterpret_cast<void*>(address_arg);
1062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    void* answer =
1063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        (redirector == NULL) ? address : (*redirector)(isolate, address, type);
1064d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    return answer;
1065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void* address_;
1068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
1069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1070c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochV8_EXPORT_PRIVATE bool operator==(ExternalReference, ExternalReference);
1071958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool operator!=(ExternalReference, ExternalReference);
1072958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1073958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniersize_t hash_value(ExternalReference);
1074958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1075c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochV8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, ExternalReference);
1076958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
10773e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu// -----------------------------------------------------------------------------
1078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Utility functions
107962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid* libc_memchr(void* string, int character, size_t search_length);
1080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
10813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline int NumberOfBitsSet(uint32_t x) {
10823100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  unsigned int num_bits_set;
10833100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  for (num_bits_set = 0; x; x >>= 1) {
10843100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    num_bits_set += x & 1;
10853100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  }
10863100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  return num_bits_set;
10873100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
1088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1089b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Computes pow(x, y) with the special cases in the spec for Math.pow.
1090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochdouble power_helper(Isolate* isolate, double x, double y);
1091b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochdouble power_double_int(double x, int y);
1092b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochdouble power_double_double(double x, double y);
1093b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1094257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Helper class for generating code or data associated with the code
1095257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// right after a call instruction. As an example this can be used to
1096257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// generate safepoint data after calls for crankshaft.
1097257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass CallWrapper {
1098257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public:
1099257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  CallWrapper() { }
1100257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  virtual ~CallWrapper() { }
1101257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Called just before emitting a call. Argument is the size of the generated
1102257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // call code.
1103257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  virtual void BeforeCall(int call_size) const = 0;
1104257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Called just after emitting a call, i.e., at the return site for the call.
1105257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  virtual void AfterCall() const = 0;
1106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Return whether call needs to check for debug stepping.
110762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  virtual bool NeedsDebugHookCheck() const { return false; }
1108257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch};
1109257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1111257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass NullCallWrapper : public CallWrapper {
1112257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public:
1113257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  NullCallWrapper() { }
1114257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  virtual ~NullCallWrapper() { }
1115257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  virtual void BeforeCall(int call_size) const { }
1116257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  virtual void AfterCall() const { }
1117257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch};
1118257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass CheckDebugStepCallWrapper : public CallWrapper {
1121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
1122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CheckDebugStepCallWrapper() {}
1123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  virtual ~CheckDebugStepCallWrapper() {}
1124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  virtual void BeforeCall(int call_size) const {}
1125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  virtual void AfterCall() const {}
112662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  virtual bool NeedsDebugHookCheck() const { return true; }
1127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
1128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// -----------------------------------------------------------------------------
1131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Constant pool support
1132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass ConstantPoolEntry {
1134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
1135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ConstantPoolEntry() {}
1136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ConstantPoolEntry(int position, intptr_t value, bool sharing_ok)
1137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : position_(position),
1138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        merged_index_(sharing_ok ? SHARING_ALLOWED : SHARING_PROHIBITED),
1139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        value_(value) {}
1140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ConstantPoolEntry(int position, double value)
1141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : position_(position), merged_index_(SHARING_ALLOWED), value64_(value) {}
1142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int position() const { return position_; }
1144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool sharing_ok() const { return merged_index_ != SHARING_PROHIBITED; }
1145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool is_merged() const { return merged_index_ >= 0; }
1146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int merged_index(void) const {
1147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(is_merged());
1148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return merged_index_;
1149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_merged_index(int index) {
1151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    merged_index_ = index;
1152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(is_merged());
1153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int offset(void) const {
1155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(merged_index_ >= 0);
1156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return merged_index_;
1157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_offset(int offset) {
1159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(offset >= 0);
1160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    merged_index_ = offset;
1161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  intptr_t value() const { return value_; }
1163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint64_t value64() const { return bit_cast<uint64_t>(value64_); }
1164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum Type { INTPTR, DOUBLE, NUMBER_OF_TYPES };
1166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static int size(Type type) {
1168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return (type == INTPTR) ? kPointerSize : kDoubleSize;
1169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum Access { REGULAR, OVERFLOWED };
1172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
1174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int position_;
1175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int merged_index_;
1176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  union {
1177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    intptr_t value_;
1178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    double value64_;
1179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
1180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum { SHARING_PROHIBITED = -2, SHARING_ALLOWED = -1 };
1181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
1182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// -----------------------------------------------------------------------------
1185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Embedded constant pool support
1186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass ConstantPoolBuilder BASE_EMBEDDED {
1188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
1189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ConstantPoolBuilder(int ptr_reach_bits, int double_reach_bits);
1190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Add pointer-sized constant to the embedded constant pool
1192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ConstantPoolEntry::Access AddEntry(int position, intptr_t value,
1193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     bool sharing_ok) {
1194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ConstantPoolEntry entry(position, value, sharing_ok);
1195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return AddEntry(entry, ConstantPoolEntry::INTPTR);
1196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Add double constant to the embedded constant pool
1199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ConstantPoolEntry::Access AddEntry(int position, double value) {
1200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ConstantPoolEntry entry(position, value);
1201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return AddEntry(entry, ConstantPoolEntry::DOUBLE);
1202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Previews the access type required for the next new entry to be added.
1205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ConstantPoolEntry::Access NextAccess(ConstantPoolEntry::Type type) const;
1206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsEmpty() {
1208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return info_[ConstantPoolEntry::INTPTR].entries.empty() &&
1209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           info_[ConstantPoolEntry::INTPTR].shared_entries.empty() &&
1210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           info_[ConstantPoolEntry::DOUBLE].entries.empty() &&
1211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           info_[ConstantPoolEntry::DOUBLE].shared_entries.empty();
1212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Emit the constant pool.  Invoke only after all entries have been
1215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // added and all instructions have been emitted.
1216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Returns position of the emitted pool (zero implies no constant pool).
1217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int Emit(Assembler* assm);
1218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Returns the label associated with the start of the constant pool.
1220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Linking to this label in the function prologue may provide an
1221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // efficient means of constant pool pointer register initialization
1222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // on some architectures.
1223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inline Label* EmittedPosition() { return &emitted_label_; }
1224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
1226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ConstantPoolEntry::Access AddEntry(ConstantPoolEntry& entry,
1227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     ConstantPoolEntry::Type type);
1228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void EmitSharedEntries(Assembler* assm, ConstantPoolEntry::Type type);
1229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void EmitGroup(Assembler* assm, ConstantPoolEntry::Access access,
1230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 ConstantPoolEntry::Type type);
1231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  struct PerTypeEntryInfo {
1233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PerTypeEntryInfo() : regular_count(0), overflow_start(-1) {}
1234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool overflow() const {
1235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return (overflow_start >= 0 &&
1236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              overflow_start < static_cast<int>(entries.size()));
1237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int regular_reach_bits;
1239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int regular_count;
1240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int overflow_start;
1241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    std::vector<ConstantPoolEntry> entries;
1242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    std::vector<ConstantPoolEntry> shared_entries;
1243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
1244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label emitted_label_;  // Records pc_offset of emitted pool
1246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PerTypeEntryInfo info_[ConstantPoolEntry::NUMBER_OF_TYPES];
1247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
1248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
1250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
1251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // V8_ASSEMBLER_H_
1252