143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Copyright (c) 1994-2006 Sun Microsystems Inc.
243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// All Rights Reserved.
343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Redistribution and use in source and binary forms, with or without
543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// modification, are permitted provided that the following conditions are
643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// met:
743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// - Redistributions of source code must retain the above copyright notice,
943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// this list of conditions and the following disclaimer.
1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// - Redistribution in binary form must reproduce the above copyright
1243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// notice, this list of conditions and the following disclaimer in the
1343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// documentation and/or other materials provided with the distribution.
1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// - Neither the name of Sun Microsystems or the names of contributors may
1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// be used to endorse or promote products derived from this software without
1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// specific prior written permission.
1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The original source code covered by the above license above has been
3243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// modified significantly by Google Inc.
33659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
3443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifndef V8_ASSEMBLER_H_
3643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define V8_ASSEMBLER_H_
3743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
38196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h"
39659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
40196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/allocation.h"
41196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/builtins.h"
42196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/gdb-jit.h"
43196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/isolate.h"
44196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/runtime.h"
45196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/token.h"
4643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
48659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
49659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.orgclass ApiFunction;
50659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
5171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
5243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
53ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgclass StatsCounter;
5443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// -----------------------------------------------------------------------------
55ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org// Platform independent assembler base class.
56ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
57ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgclass AssemblerBase: public Malloced {
58ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org public:
598e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  AssemblerBase(Isolate* isolate, void* buffer, int buffer_size);
608e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  virtual ~AssemblerBase();
61ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
62ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Isolate* isolate() const { return isolate_; }
63e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  int jit_cookie() const { return jit_cookie_; }
64e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
65e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  bool emit_debug_code() const { return emit_debug_code_; }
66e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  void set_emit_debug_code(bool value) { emit_debug_code_ = value; }
67e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
68874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  bool serializer_enabled() const { return serializer_enabled_; }
69f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org  void enable_serializer() { serializer_enabled_ = true; }
70874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org
71e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  bool predictable_code_size() const { return predictable_code_size_; }
72e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  void set_predictable_code_size(bool value) { predictable_code_size_ = value; }
73ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
74750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  uint64_t enabled_cpu_features() const { return enabled_cpu_features_; }
75750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  void set_enabled_cpu_features(uint64_t features) {
76750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    enabled_cpu_features_ = features;
77750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
78750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  bool IsEnabled(CpuFeature f) {
79750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    return (enabled_cpu_features_ & (static_cast<uint64_t>(1) << f)) != 0;
80750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
81750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
8228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  // Overwrite a host NaN with a quiet target NaN.  Used by mksnapshot for
8328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  // cross-snapshotting.
8428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  static void QuietNaN(HeapObject* nan) { }
8528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
868e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  int pc_offset() const { return static_cast<int>(pc_ - buffer_); }
878e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
8886b1631344aedfc4be5dcd5237e28d0b28e5974emachenbach@chromium.org  // This function is called when code generation is aborted, so that
8986b1631344aedfc4be5dcd5237e28d0b28e5974emachenbach@chromium.org  // the assembler could clean up internal data structures.
9086b1631344aedfc4be5dcd5237e28d0b28e5974emachenbach@chromium.org  virtual void AbortedCodeGeneration() { }
9186b1631344aedfc4be5dcd5237e28d0b28e5974emachenbach@chromium.org
928e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  static const int kMinimalBufferSize = 4*KB;
938e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
948e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org protected:
958e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  // The buffer into which code and relocation info are generated. It could
968e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  // either be owned by the assembler or be provided externally.
978e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  byte* buffer_;
988e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  int buffer_size_;
998e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  bool own_buffer_;
1008e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
1018e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  // The program counter, which points into the buffer above and moves forward.
1028e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  byte* pc_;
1038e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
104ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org private:
105ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Isolate* isolate_;
1067304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  int jit_cookie_;
107750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  uint64_t enabled_cpu_features_;
108e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  bool emit_debug_code_;
109e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  bool predictable_code_size_;
110874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  bool serializer_enabled_;
111e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org};
112e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
113e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
114731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org// Avoids emitting debug code during the lifetime of this scope object.
115731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.orgclass DontEmitDebugCodeScope BASE_EMBEDDED {
116731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org public:
117731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org  explicit DontEmitDebugCodeScope(AssemblerBase* assembler)
118731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      : assembler_(assembler), old_value_(assembler->emit_debug_code()) {
119731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    assembler_->set_emit_debug_code(false);
120731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org  }
121731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org  ~DontEmitDebugCodeScope() {
122731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    assembler_->set_emit_debug_code(old_value_);
1233c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  }
124731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org private:
125731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org  AssemblerBase* assembler_;
126731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org  bool old_value_;
127731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org};
128731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org
129731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org
130e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org// Avoids using instructions that vary in size in unpredictable ways between the
131e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org// snapshot and the running VM.
132e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgclass PredictableCodeSizeScope {
133e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org public:
1348e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  PredictableCodeSizeScope(AssemblerBase* assembler, int expected_size);
1358e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  ~PredictableCodeSizeScope();
136e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
137e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org private:
138e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  AssemblerBase* assembler_;
1398e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  int expected_size_;
1408e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  int start_offset_;
141e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  bool old_value_;
142ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org};
143ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
144a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
145750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// Enable a specified feature within a scope.
146750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgclass CpuFeatureScope BASE_EMBEDDED {
147750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org public:
148750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org#ifdef DEBUG
149750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CpuFeatureScope(AssemblerBase* assembler, CpuFeature f);
150750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  ~CpuFeatureScope();
151750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
152750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org private:
153750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  AssemblerBase* assembler_;
154750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  uint64_t old_enabled_;
155750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org#else
156750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CpuFeatureScope(AssemblerBase* assembler, CpuFeature f) {}
157750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org#endif
158750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org};
159750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
160750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
161874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org// CpuFeatures keeps track of which features are supported by the target CPU.
162874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org// Supported features must be enabled by a CpuFeatureScope before use.
163874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org// Example:
164874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org//   if (assembler->IsSupported(SSE3)) {
165874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org//     CpuFeatureScope fscope(assembler, SSE3);
166874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org//     // Generate code containing SSE3 instructions.
167874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org//   } else {
168874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org//     // Generate alternative code.
169874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org//   }
170874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.orgclass CpuFeatures : public AllStatic {
171528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org public:
172874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  static void Probe(bool cross_compile) {
173874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org    STATIC_ASSERT(NUMBER_OF_CPU_FEATURES <= kBitsPerInt);
174874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org    if (initialized_) return;
175874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org    initialized_ = true;
176874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org    ProbeImpl(cross_compile);
177874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  }
178874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org
1793e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  static unsigned SupportedFeatures() {
1803e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    Probe(false);
1813e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    return supported_;
1823e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  }
1833e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
184874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  static bool IsSupported(CpuFeature f) {
185874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org    return (supported_ & (1u << f)) != 0;
186874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  }
187874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org
188874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  static inline bool SupportsCrankshaft();
189874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org
190874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  static inline unsigned cache_line_size() {
191e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(cache_line_size_ != 0);
192874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org    return cache_line_size_;
193874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  }
194874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org
195874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  static void PrintTarget();
196874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  static void PrintFeatures();
197528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
1985de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  // Flush instruction cache.
1995de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  static void FlushICache(void* start, size_t size);
2005de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org
201528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org private:
202874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  // Platform-dependent implementation.
203874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  static void ProbeImpl(bool cross_compile);
204874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org
205874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  static unsigned supported_;
206874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  static unsigned cache_line_size_;
207874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  static bool initialized_;
208874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  friend class ExternalReference;
209874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  DISALLOW_COPY_AND_ASSIGN(CpuFeatures);
210528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org};
211528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
212528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
213a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// -----------------------------------------------------------------------------
21443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Labels represent pc locations; they are typically jump or call targets.
21543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// After declaration, a label can be freely used to denote known or (yet)
21643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// unknown pc location. Assembler::bind() is used to bind a label to the
21743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// current pc. A label can be bound only once.
21843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2197be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.orgclass Label BASE_EMBEDDED {
22043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
22183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  enum Distance {
22283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    kNear, kFar
22383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  };
22483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
22583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  INLINE(Label()) {
22683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Unuse();
22783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    UnuseNear();
22883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
22943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2307b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  INLINE(~Label()) {
231e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!is_linked());
232e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!is_near_linked());
2337b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  }
2347b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
2357b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  INLINE(void Unuse()) { pos_ = 0; }
2367b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  INLINE(void UnuseNear()) { near_link_pos_ = 0; }
23743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2387b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  INLINE(bool is_bound() const) { return pos_ <  0; }
2397b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  INLINE(bool is_unused() const) { return pos_ == 0 && near_link_pos_ == 0; }
2407b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  INLINE(bool is_linked() const) { return pos_ >  0; }
24183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  INLINE(bool is_near_linked() const) { return near_link_pos_ > 0; }
24243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
24343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Returns the position of bound or linked labels. Cannot be used
24443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // for unused labels.
24543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int pos() const;
24683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  int near_link_pos() const { return near_link_pos_ - 1; }
24743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
24843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
24943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // pos_ encodes both the binding state (via its sign)
25043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // and the binding position (via its value) of a label.
25143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
25243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // pos_ <  0  bound label, pos() returns the jump target position
25343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // pos_ == 0  unused label
25443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // pos_ >  0  linked label, pos() returns the last reference position
25543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int pos_;
25643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
25783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Behaves like |pos_| in the "> 0" case, but for near jumps to this label.
25883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  int near_link_pos_;
25983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
26043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void bind_to(int pos)  {
26143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    pos_ = -pos - 1;
262e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(is_bound());
26343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
26483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void link_to(int pos, Distance distance = kFar) {
26583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    if (distance == kNear) {
26683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      near_link_pos_ = pos + 1;
267e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(is_near_linked());
26883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    } else {
26983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      pos_ = pos + 1;
270e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(is_linked());
27183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    }
27243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
27343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
27443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  friend class Assembler;
27543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  friend class Displacement;
276a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  friend class RegExpMacroAssemblerIrregexp;
2776b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org
278fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org#if V8_TARGET_ARCH_ARM64
279fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  // On ARM64, the Assembler keeps track of pointers to Labels to resolve
280fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  // branches to distant targets. Copying labels would confuse the Assembler.
2816b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org  DISALLOW_COPY_AND_ASSIGN(Label);  // NOLINT
2826b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org#endif
28343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
28443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
28543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
286c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comenum SaveFPRegsMode { kDontSaveFPRegs, kSaveFPRegs };
287c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
2886a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org// Specifies whether to perform icache flush operations on RelocInfo updates.
2896a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org// If FLUSH_ICACHE_IF_NEEDED, the icache will always be flushed if an
2906a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org// instruction was modified. If SKIP_ICACHE_FLUSH the flush will always be
2916a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org// skipped (only use this if you will flush the icache manually before it is
2926a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org// executed).
2936a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.orgenum ICacheFlushMode { FLUSH_ICACHE_IF_NEEDED, SKIP_ICACHE_FLUSH };
294c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
29543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// -----------------------------------------------------------------------------
29643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Relocation information
29743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
29843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
29943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Relocation information consists of the address (pc) of the datum
30043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// to which the relocation information applies, the relocation mode
30143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// (rmode), and an optional data field. The relocation mode may be
30243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// "descriptive" and not indicate a need for relocation, but simply
30343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// describe a property of the datum. Such rmodes are useful for GC
30443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// and nice disassembly output.
30543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3063484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.orgclass RelocInfo {
30743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
308236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  // The constant kNoPosition is used with the collecting of source positions
309236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  // in the relocation information. Two types of source positions are collected
310236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  // "position" (RelocMode position) and "statement position" (RelocMode
311236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  // statement_position). The "position" is collected at places in the source
312236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  // code which are of interest when making stack traces to pin-point the source
313236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  // location of a stack frame as close as possible. The "statement position" is
314236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  // collected at the beginning at each statement, and is used to indicate
315236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  // possible break locations. kNoPosition is used to indicate an
316236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  // invalid/uninitialized position value.
317236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  static const int kNoPosition = -1;
318236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
31949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  // This string is used to add padding comments to the reloc info in cases
32049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  // where we are not sure to have enough space for patching in during
32149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  // lazy deoptimization. This is the case if we have indirect calls for which
32249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  // we do not normally record relocation info.
3237c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  static const char* const kFillerCommentString;
32449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
3252233451cf5880608b0e9100e3736ddd4472b4024ricow@chromium.org  // The minimum size of a comment is equal to three bytes for the extra tagged
3262233451cf5880608b0e9100e3736ddd4472b4024ricow@chromium.org  // pc + the tag for the data, and kPointerSize for the actual pointer to the
3273a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // comment.
3282233451cf5880608b0e9100e3736ddd4472b4024ricow@chromium.org  static const int kMinRelocCommentSize = 3 + kPointerSize;
3293a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
3303a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // The maximum size for a call instruction including pc-jump.
3313a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  static const int kMaxCallSize = 6;
3323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
3337979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  // The maximum pc delta that will use the short encoding.
3347979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  static const int kMaxSmallPCDelta;
3357979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org
336236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  enum Mode {
337236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    // Please note the order is important (see IsCodeTarget, IsGCRelocMode).
3388e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    CODE_TARGET,  // Code target which is not any of the above.
3398e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    CODE_TARGET_WITH_ID,
340236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    CONSTRUCT_CALL,  // code target that is a call to a JavaScript constructor.
3412356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org    DEBUG_BREAK,  // Code target for the debugger statement.
342236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    EMBEDDED_OBJECT,
34341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    CELL,
344a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
345236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    // Everything after runtime_entry (inclusive) is not GC'ed.
346236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    RUNTIME_ENTRY,
347236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    JS_RETURN,  // Marks start of the ExitJSFrame code.
348236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    COMMENT,
349236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    POSITION,  // See comment for kNoPosition above.
350236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    STATEMENT_POSITION,  // See comment for kNoPosition above.
3512356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org    DEBUG_BREAK_SLOT,  // Additional code inserted for debug break slot.
352236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    EXTERNAL_REFERENCE,  // The address of an external C++ function.
353236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    INTERNAL_REFERENCE,  // An address inside the same function.
354236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
355fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    // Marks constant and veneer pools. Only used on ARM and ARM64.
35697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    // They use a custom noncompact encoding.
3575a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    CONST_POOL,
35897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    VENEER_POOL,
3595a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
360236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    // add more as needed
361236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    // Pseudo-types
3625a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    NUMBER_OF_MODES,  // There are at most 15 modes with noncompact encoding.
36359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    NONE32,  // never recorded 32-bit value
3644cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    NONE64,  // never recorded 64-bit value
365e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    CODE_AGE_SEQUENCE,  // Not stored in RelocInfo array, used explictly by
366e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org                        // code aging.
367e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    FIRST_REAL_RELOC_MODE = CODE_TARGET,
36897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    LAST_REAL_RELOC_MODE = VENEER_POOL,
369e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    FIRST_PSEUDO_RELOC_MODE = CODE_AGE_SEQUENCE,
370e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    LAST_PSEUDO_RELOC_MODE = CODE_AGE_SEQUENCE,
3718e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    LAST_CODE_ENUM = DEBUG_BREAK,
37241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    LAST_GCED_ENUM = CELL,
3738e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    // Modes <= LAST_COMPACT_ENUM are guaranteed to have compact encoding.
3745a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    LAST_COMPACT_ENUM = CODE_TARGET_WITH_ID,
3755a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    LAST_STANDARD_NONCOMPACT_ENUM = INTERNAL_REFERENCE
376236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  };
377236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
37843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RelocInfo() {}
379c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
380c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  RelocInfo(byte* pc, Mode rmode, intptr_t data, Code* host)
381c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      : pc_(pc), rmode_(rmode), data_(data), host_(host) {
38243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
3834cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  RelocInfo(byte* pc, double data64)
3844cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      : pc_(pc), rmode_(NONE64), data64_(data64), host_(NULL) {
3854cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  }
38643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
387e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  static inline bool IsRealRelocMode(Mode mode) {
388e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    return mode >= FIRST_REAL_RELOC_MODE &&
389e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org        mode <= LAST_REAL_RELOC_MODE;
390e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
391e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  static inline bool IsPseudoRelocMode(Mode mode) {
392e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!IsRealRelocMode(mode));
393e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    return mode >= FIRST_PSEUDO_RELOC_MODE &&
394e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org        mode <= LAST_PSEUDO_RELOC_MODE;
395e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
396236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  static inline bool IsConstructCall(Mode mode) {
397236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    return mode == CONSTRUCT_CALL;
398236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  }
399236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  static inline bool IsCodeTarget(Mode mode) {
400236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    return mode <= LAST_CODE_ENUM;
401236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  }
402b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  static inline bool IsEmbeddedObject(Mode mode) {
403b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    return mode == EMBEDDED_OBJECT;
404b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  }
4056e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  static inline bool IsRuntimeEntry(Mode mode) {
4066e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    return mode == RUNTIME_ENTRY;
4076e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  }
408236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  // Is the relocation mode affected by GC?
409236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  static inline bool IsGCRelocMode(Mode mode) {
410236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    return mode <= LAST_GCED_ENUM;
411236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  }
412236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  static inline bool IsJSReturn(Mode mode) {
413236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    return mode == JS_RETURN;
414236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  }
415236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  static inline bool IsComment(Mode mode) {
416236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    return mode == COMMENT;
417236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  }
4185a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  static inline bool IsConstPool(Mode mode) {
4195a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    return mode == CONST_POOL;
4205a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  }
42197b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  static inline bool IsVeneerPool(Mode mode) {
42297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    return mode == VENEER_POOL;
42397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  }
424236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  static inline bool IsPosition(Mode mode) {
425236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    return mode == POSITION || mode == STATEMENT_POSITION;
426236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  }
427236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  static inline bool IsStatementPosition(Mode mode) {
428236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    return mode == STATEMENT_POSITION;
429236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  }
430236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  static inline bool IsExternalReference(Mode mode) {
431236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    return mode == EXTERNAL_REFERENCE;
432236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  }
433236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  static inline bool IsInternalReference(Mode mode) {
434236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    return mode == INTERNAL_REFERENCE;
435236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  }
4362356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  static inline bool IsDebugBreakSlot(Mode mode) {
4372356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org    return mode == DEBUG_BREAK_SLOT;
4382356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  }
4394cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  static inline bool IsNone(Mode mode) {
44059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    return mode == NONE32 || mode == NONE64;
4414cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  }
442e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  static inline bool IsCodeAgeSequence(Mode mode) {
443e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    return mode == CODE_AGE_SEQUENCE;
444e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
445236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  static inline int ModeMask(Mode mode) { return 1 << mode; }
446236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
447763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  // Returns true if the first RelocInfo has the same mode and raw data as the
448763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  // second one.
449763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  static inline bool IsEqual(RelocInfo first, RelocInfo second) {
450763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    return first.rmode() == second.rmode() &&
451763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org           (first.rmode() == RelocInfo::NONE64 ?
452763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org              first.raw_data64() == second.raw_data64() :
453763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org              first.data() == second.data());
454763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  }
455763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org
45643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Accessors
4574a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  byte* pc() const { return pc_; }
45843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void set_pc(byte* pc) { pc_ = pc; }
459236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  Mode rmode() const {  return rmode_; }
4604a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  intptr_t data() const { return data_; }
4614cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  double data64() const { return data64_; }
462e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  uint64_t raw_data64() { return bit_cast<uint64_t>(data64_); }
463c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Code* host() const { return host_; }
46497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  void set_host(Code* host) { host_ = host; }
46543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
46643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Apply a relocation by delta bytes
4676a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  INLINE(void apply(intptr_t delta,
4686a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                    ICacheFlushMode icache_flush_mode =
4696a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                        FLUSH_ICACHE_IF_NEEDED));
47043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4719dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  // Is the pointer this relocation info refers to coded like a plain pointer
4722efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // or is it strange in some way (e.g. relative or patched into a series of
4739dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  // instructions).
4749dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  bool IsCodedSpecially();
4759dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
476bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org  // If true, the pointer this relocation info refers to is an entry in the
477bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org  // constant pool, otherwise the pointer is embedded in the instruction stream.
478bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org  bool IsInConstantPool();
479bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org
4803291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  // Read/modify the code target in the branch/call instruction
4813291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  // this relocation applies to;
4822bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  // can only be called if IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)
48343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  INLINE(Address target_address());
484394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  INLINE(void set_target_address(Address target,
4856a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                 WriteBarrierMode write_barrier_mode =
4866a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                     UPDATE_WRITE_BARRIER,
4876a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                 ICacheFlushMode icache_flush_mode =
4886a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                     FLUSH_ICACHE_IF_NEEDED));
48943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  INLINE(Object* target_object());
490c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  INLINE(Handle<Object> target_object_handle(Assembler* origin));
491394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  INLINE(void set_target_object(Object* target,
4926a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                WriteBarrierMode write_barrier_mode =
4936a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                    UPDATE_WRITE_BARRIER,
4946a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                ICacheFlushMode icache_flush_mode =
4956a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                    FLUSH_ICACHE_IF_NEEDED));
4966e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  INLINE(Address target_runtime_entry(Assembler* origin));
4976e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  INLINE(void set_target_runtime_entry(Address target,
4986a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                       WriteBarrierMode write_barrier_mode =
4996a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                           UPDATE_WRITE_BARRIER,
5006a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                       ICacheFlushMode icache_flush_mode =
5016a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                           FLUSH_ICACHE_IF_NEEDED));
50241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  INLINE(Cell* target_cell());
50341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  INLINE(Handle<Cell> target_cell_handle());
50441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  INLINE(void set_target_cell(Cell* cell,
5056a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                              WriteBarrierMode write_barrier_mode =
5066a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                  UPDATE_WRITE_BARRIER,
5076a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                              ICacheFlushMode icache_flush_mode =
5086a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                  FLUSH_ICACHE_IF_NEEDED));
509c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  INLINE(Handle<Object> code_age_stub_handle(Assembler* origin));
510e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  INLINE(Code* code_age_stub());
5116a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  INLINE(void set_code_age_stub(Code* stub,
5126a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                ICacheFlushMode icache_flush_mode =
5136a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                    FLUSH_ICACHE_IF_NEEDED));
51443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
515bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org  // Returns the address of the constant pool entry where the target address
516bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org  // is held.  This should only be called if IsInConstantPool returns true.
517bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org  INLINE(Address constant_pool_entry_address());
518bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org
5199155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // Read the address of the word containing the target_address in an
5209155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // instruction stream.  What this means exactly is architecture-independent.
5219155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // The only architecture-independent user of this function is the serializer.
5229155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // The serializer uses it to find out how many raw bytes of instruction to
5239155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // output before the next target.  Architecture-independent code shouldn't
5249155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // dereference the pointer it gets back from this.
5253291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  INLINE(Address target_address_address());
526bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org
5279155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // This indicates how much space a target takes up when deserializing a code
5289155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // stream.  For most architectures this is just the size of a pointer.  For
5299155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // an instruction like movw/movt where the target bits are mixed into the
5309155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // instruction bits the size of the target will be zero, indicating that the
5319155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // serializer should not step forwards in memory after a target is resolved
5329155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // and written.  In this case the target_address_address function above
5339155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // should return the end of the instructions to be patched, allowing the
5349155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // deserializer to deserialize the instructions as raw bytes and put them in
5359155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // place, ready to be patched with the target.
5369155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  INLINE(int target_address_size());
5373291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
53843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Read/modify the reference in the instruction this relocation
53943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // applies to; can only be called if rmode_ is external_reference
540057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  INLINE(Address target_reference());
54143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
54243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Read/modify the address of a call instruction. This is used to relocate
54343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // the break points where straight-line code is patched with a call
54443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // instruction.
54543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  INLINE(Address call_address());
54643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  INLINE(void set_call_address(Address target));
54743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  INLINE(Object* call_object());
54843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  INLINE(void set_call_object(Object* target));
549c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org  INLINE(Object** call_object_address());
55043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
551057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  // Wipe out a relocation to a fixed value, used for making snapshots
552057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  // reproducible.
553057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  INLINE(void WipeOut());
554057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
555ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  template<typename StaticVisitor> inline void Visit(Heap* heap);
556e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org  inline void Visit(Isolate* isolate, ObjectVisitor* v);
5579155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
55843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Patch the code with some other code.
559245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org  void PatchCode(byte* instructions, int instruction_count);
56043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
56143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Patch the code with a call.
562245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org  void PatchCodeWithCall(Address target, int guard_bytes);
5639d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com
5649d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  // Check whether this return sequence has been patched
5659d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  // with a call to the debugger.
5669d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  INLINE(bool IsPatchedReturnSequence());
56743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5682356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  // Check whether this debug break slot has been patched with a call to the
5692356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  // debugger.
5702356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  INLINE(bool IsPatchedDebugBreakSlotSequence());
5712356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org
5722e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#ifdef DEBUG
5732e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // Check whether the given code contains relocation information that
5742e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // either is position-relative or movable by the garbage collector.
5752e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  static bool RequiresRelocation(const CodeDesc& desc);
5762e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#endif
5772e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
578769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com#ifdef ENABLE_DISASSEMBLER
579769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com  // Printing
580236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  static const char* RelocModeName(Mode rmode);
581f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  void Print(Isolate* isolate, OStream& os);  // NOLINT
582769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com#endif  // ENABLE_DISASSEMBLER
583c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
5845924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org  void Verify(Isolate* isolate);
58543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
58643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
587236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  static const int kCodeTargetMask = (1 << (LAST_CODE_ENUM + 1)) - 1;
588236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  static const int kPositionMask = 1 << POSITION | 1 << STATEMENT_POSITION;
5898e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  static const int kDataMask =
5908e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      (1 << CODE_TARGET_WITH_ID) | kPositionMask | (1 << COMMENT);
59143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  static const int kApplyMask;  // Modes affected by apply. Depends on arch.
59243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
59343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
59443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // On ARM, note that pc_ is the address of the constant pool entry
59543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // to be relocated and not the address of the instruction
59643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // referencing the constant pool entry (except when rmode_ ==
59743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // comment).
59843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  byte* pc_;
599236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  Mode rmode_;
6004cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  union {
6014cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    intptr_t data_;
6024cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    double data64_;
6034cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  };
604c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Code* host_;
60540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // External-reference pointers are also split across instruction-pairs
60689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // on some platforms, but are accessed via indirect pointers. This location
60740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // provides a place for that pointer to exist naturally. Its address
60840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // is returned by RelocInfo::target_reference_address().
60940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  Address reconstructed_adr_ptr_;
61043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  friend class RelocIterator;
61143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
61243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
61343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
61443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// RelocInfoWriter serializes a stream of relocation info. It writes towards
61543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// lower addresses.
61643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass RelocInfoWriter BASE_EMBEDDED {
61743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
6188e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  RelocInfoWriter() : pos_(NULL),
6198e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                      last_pc_(NULL),
6208e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                      last_id_(0),
6218e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                      last_position_(0) {}
6228e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  RelocInfoWriter(byte* pos, byte* pc) : pos_(pos),
6238e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                                         last_pc_(pc),
6248e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                                         last_id_(0),
6258e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                                         last_position_(0) {}
62643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
62743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  byte* pos() const { return pos_; }
62843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  byte* last_pc() const { return last_pc_; }
62943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
63043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void Write(const RelocInfo* rinfo);
63143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
63243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Update the state of the stream after reloc info buffer
63343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // and/or code is moved while the stream is active.
63443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void Reposition(byte* pos, byte* pc) {
63543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    pos_ = pos;
63643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    last_pc_ = pc;
63743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
63843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6393e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  // Max size (bytes) of a written RelocInfo. Longest encoding is
6403e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  // ExtraTag, VariableLengthPCJump, ExtraTag, pc_delta, ExtraTag, data_delta.
6413e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  // On ia32 and arm this is 1 + 4 + 1 + 1 + 1 + 4 = 12.
6423e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  // On x64 this is 1 + 4 + 1 + 1 + 1 + 8 == 16;
6433e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  // Here we use the maximum of the two.
6443e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  static const int kMaxSize = 16;
64543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
64643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
64743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline uint32_t WriteVariableLengthPCJump(uint32_t pc_delta);
64843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline void WriteTaggedPC(uint32_t pc_delta, int tag);
64943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline void WriteExtraTaggedPC(uint32_t pc_delta, int extra_tag);
6508e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  inline void WriteExtraTaggedIntData(int data_delta, int top_tag);
65197b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  inline void WriteExtraTaggedPoolData(int data, int pool_type);
652e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org  inline void WriteExtraTaggedData(intptr_t data_delta, int top_tag);
653e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org  inline void WriteTaggedData(intptr_t data_delta, int tag);
65443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline void WriteExtraTag(int extra_tag, int top_tag);
65543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
65643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  byte* pos_;
65743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  byte* last_pc_;
6588e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  int last_id_;
6598e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  int last_position_;
6609a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  DISALLOW_COPY_AND_ASSIGN(RelocInfoWriter);
66143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
66243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
66343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
66443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// A RelocIterator iterates over relocation information.
66543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Typical use:
66643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
66743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//   for (RelocIterator it(code); !it.done(); it.next()) {
66843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//     // do something with it.rinfo() here
66943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//   }
67043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
67143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// A mask can be specified to skip unwanted modes.
67243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass RelocIterator: public Malloced {
67343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
67443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Create a new iterator positioned at
67543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // the beginning of the reloc info.
67643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Relocation information with mode k is included in the
67743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // iteration iff bit k of mode_mask is set.
67843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  explicit RelocIterator(Code* code, int mode_mask = -1);
67943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  explicit RelocIterator(const CodeDesc& desc, int mode_mask = -1);
68043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
68143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Iteration
6824a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  bool done() const { return done_; }
68343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void next();
68443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
68543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Return pointer valid until next next().
68643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RelocInfo* rinfo() {
687e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!done());
68843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return &rinfo_;
68943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
69043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
69143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
69243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Advance* moves the position before/after reading.
69343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // *Read* reads from current byte(s) into rinfo_.
69443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // *Get* just reads and returns info on current byte.
69543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void Advance(int bytes = 1) { pos_ -= bytes; }
69643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int AdvanceGetTag();
69743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int GetExtraTag();
69843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int GetTopTag();
69943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void ReadTaggedPC();
70043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void AdvanceReadPC();
7018e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  void AdvanceReadId();
70297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  void AdvanceReadPoolData();
7038e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  void AdvanceReadPosition();
70443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void AdvanceReadData();
70543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void AdvanceReadVariableLengthPCJump();
7068e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  int GetLocatableTypeTag();
7078e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  void ReadTaggedId();
7088e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  void ReadTaggedPosition();
70943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
71043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If the given mode is wanted, set it in rinfo_ and return true.
71143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Else return false. Used for efficiently skipping unwanted modes.
712236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  bool SetMode(RelocInfo::Mode mode) {
713a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return (mode_mask_ & (1 << mode)) ? (rinfo_.rmode_ = mode, true) : false;
71443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
71543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
71643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  byte* pos_;
71743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  byte* end_;
718e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  byte* code_age_sequence_;
71943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RelocInfo rinfo_;
72043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool done_;
72143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int mode_mask_;
7228e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  int last_id_;
7238e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  int last_position_;
7249a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  DISALLOW_COPY_AND_ASSIGN(RelocIterator);
72543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
72643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
72743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
72843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//------------------------------------------------------------------------------
72943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// External function
73043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
73143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//----------------------------------------------------------------------------
73243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass IC_Utility;
73343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass SCTableReference;
73465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.orgclass Debug_Address;
73543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
736eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
737eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org// An ExternalReference represents a C++ address used in the generated
738eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org// code. All references to C++ functions and variables must be encapsulated in
739eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org// an ExternalReference instance. This is done in order to track the origin of
740eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org// all external references in the code so that they can be bound to the correct
741eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org// addresses when deserializing a heap.
74243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass ExternalReference BASE_EMBEDDED {
74343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
74483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  // Used in the simulator to support different native api calls.
74583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  enum Type {
7465d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    // Builtin call.
747a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    // Object* f(v8::internal::Arguments).
74883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org    BUILTIN_CALL,  // default
7495d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org
7508e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    // Builtin that takes float arguments and returns an int.
7518e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    // int f(double, double).
7528e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    BUILTIN_COMPARE_CALL,
7538e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
7545d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    // Builtin call that returns floating point.
7555d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    // double f(double, double).
7568e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    BUILTIN_FP_FP_CALL,
7578e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
7588e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    // Builtin call that returns floating point.
7598e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    // double f(double).
7608e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    BUILTIN_FP_CALL,
7618e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
7628e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    // Builtin call that returns floating point.
7638e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    // double f(double, int).
7648e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    BUILTIN_FP_INT_CALL,
7655d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org
7665d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    // Direct call to API function callback.
767662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    // void f(v8::FunctionCallbackInfo&)
7685d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    DIRECT_API_CALL,
7695d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org
770b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    // Call to function callback via InvokeFunctionCallback.
771662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    // void f(v8::FunctionCallbackInfo&, v8::FunctionCallback)
772662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    PROFILING_API_CALL,
773b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
7745d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    // Direct call to accessor getter callback.
775e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    // void f(Local<Name> property, PropertyCallbackInfo& info)
776bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org    DIRECT_GETTER_CALL,
777bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org
778b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    // Call to accessor getter callback via InvokeAccessorGetterCallback.
779e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    // void f(Local<Name> property, PropertyCallbackInfo& info,
780e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    //     AccessorNameGetterCallback callback)
781662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    PROFILING_GETTER_CALL
78283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  };
78383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
7847d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org  static void SetUp();
7851f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org  static void InitializeMathExpData();
7861f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org  static void TearDownMathExpData();
7877d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org
78883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  typedef void* ExternalReferenceRedirector(void* original, Type type);
78983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
790d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  ExternalReference() : address_(NULL) {}
791d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
792ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ExternalReference(Builtins::CFunctionId id, Isolate* isolate);
79343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
794ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ExternalReference(ApiFunction* ptr, Type type, Isolate* isolate);
795c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
796ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ExternalReference(Builtins::Name name, Isolate* isolate);
79743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
798ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ExternalReference(Runtime::FunctionId id, Isolate* isolate);
79943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
800ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ExternalReference(const Runtime::Function* f, Isolate* isolate);
80143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
802ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ExternalReference(const IC_Utility& ic_utility, Isolate* isolate);
80343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
80443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  explicit ExternalReference(StatsCounter* counter);
80543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
806ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ExternalReference(Isolate::AddressId id, Isolate* isolate);
80743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
80843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  explicit ExternalReference(const SCTableReference& table_ref);
80943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8108fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  // Isolate as an external reference.
81132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  static ExternalReference isolate_address(Isolate* isolate);
812ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
81343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // One-of-a-kind references. These references are not part of a general
81443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // pattern. This means that they have to be added to the
81543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // ExternalReferenceTable in serialize.cc manually.
81643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
817c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  static ExternalReference incremental_marking_record_write_function(
818c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Isolate* isolate);
819c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  static ExternalReference store_buffer_overflow_function(
820c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Isolate* isolate);
821c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  static ExternalReference flush_icache_function(Isolate* isolate);
822ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  static ExternalReference delete_handle_scope_extensions(Isolate* isolate);
82343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8244efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  static ExternalReference get_date_field_function(Isolate* isolate);
8254efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  static ExternalReference date_cache_stamp(Isolate* isolate);
8264efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
827e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  static ExternalReference get_make_code_young_function(Isolate* isolate);
828c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  static ExternalReference get_mark_code_as_executed_function(Isolate* isolate);
829e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
830a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Deoptimization support.
831ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  static ExternalReference new_deoptimizer_function(Isolate* isolate);
832ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  static ExternalReference compute_output_frames_function(Isolate* isolate);
833a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
83483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  // Log support.
83583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  static ExternalReference log_enter_external_function(Isolate* isolate);
83683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  static ExternalReference log_leave_external_function(Isolate* isolate);
83783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
83813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Static data in the keyed lookup cache.
839ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  static ExternalReference keyed_lookup_cache_keys(Isolate* isolate);
840ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  static ExternalReference keyed_lookup_cache_field_offsets(Isolate* isolate);
84113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
842394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Static variable Heap::roots_array_start()
843394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  static ExternalReference roots_array_start(Isolate* isolate);
844ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org
845ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // Static variable Heap::allocation_sites_list_address()
846ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  static ExternalReference allocation_sites_list_address(Isolate* isolate);
847ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
8486f10e41fef1524c70846d970268de222e41c594cager@chromium.org  // Static variable StackGuard::address_of_jslimit()
849ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  static ExternalReference address_of_stack_limit(Isolate* isolate);
850c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
851c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Static variable StackGuard::address_of_real_jslimit()
852ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  static ExternalReference address_of_real_stack_limit(Isolate* isolate);
85343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8543291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  // Static variable RegExpStack::limit_address()
855ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  static ExternalReference address_of_regexp_stack_limit(Isolate* isolate);
8563291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
8570c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  // Static variables for RegExp.
858ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  static ExternalReference address_of_static_offsets_vector(Isolate* isolate);
859ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  static ExternalReference address_of_regexp_stack_memory_address(
860ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      Isolate* isolate);
861ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  static ExternalReference address_of_regexp_stack_memory_size(
862ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      Isolate* isolate);
8630c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
86443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Static variable Heap::NewSpaceStart()
865ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  static ExternalReference new_space_start(Isolate* isolate);
866ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  static ExternalReference new_space_mask(Isolate* isolate);
867c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
868c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Write barrier.
869c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  static ExternalReference store_buffer_top(Isolate* isolate);
87043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
87143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Used for fast allocation in generated code.
872ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  static ExternalReference new_space_allocation_top_address(Isolate* isolate);
873ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  static ExternalReference new_space_allocation_limit_address(Isolate* isolate);
8742bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  static ExternalReference old_pointer_space_allocation_top_address(
8752bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org      Isolate* isolate);
8762bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  static ExternalReference old_pointer_space_allocation_limit_address(
8772bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org      Isolate* isolate);
878e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  static ExternalReference old_data_space_allocation_top_address(
879e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      Isolate* isolate);
880e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  static ExternalReference old_data_space_allocation_limit_address(
881e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      Isolate* isolate);
88243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8834f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  static ExternalReference mod_two_doubles_operation(Isolate* isolate);
884ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  static ExternalReference power_double_double_function(Isolate* isolate);
885ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  static ExternalReference power_double_int_function(Isolate* isolate);
88643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
88709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  static ExternalReference handle_scope_next_address(Isolate* isolate);
88809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  static ExternalReference handle_scope_limit_address(Isolate* isolate);
88909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  static ExternalReference handle_scope_level_address(Isolate* isolate);
890c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
891ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  static ExternalReference scheduled_exception_address(Isolate* isolate);
8927028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  static ExternalReference address_of_pending_message_obj(Isolate* isolate);
8937028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  static ExternalReference address_of_has_pending_message(Isolate* isolate);
8947028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  static ExternalReference address_of_pending_message_script(Isolate* isolate);
895c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
896a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Static variables containing common double constants.
897a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static ExternalReference address_of_min_int();
898a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static ExternalReference address_of_one_half();
8998432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  static ExternalReference address_of_minus_one_half();
9005f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  static ExternalReference address_of_negative_infinity();
90184bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  static ExternalReference address_of_canonical_non_hole_nan();
90284bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  static ExternalReference address_of_the_hole_nan();
903b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  static ExternalReference address_of_uint32_bias();
904a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
905ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  static ExternalReference math_log_double_function(Isolate* isolate);
9068f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
9071f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org  static ExternalReference math_exp_constants(int constant_index);
9081f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org  static ExternalReference math_exp_log_table();
9091f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org
9107028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  static ExternalReference page_flags(Page* page);
9117028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
912a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  static ExternalReference ForDeoptEntry(Address entry);
913a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
914003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  static ExternalReference cpu_features();
915003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
916975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  static ExternalReference debug_is_active_address(Isolate* isolate);
917fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  static ExternalReference debug_after_break_target_address(Isolate* isolate);
918fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  static ExternalReference debug_restarter_frame_function_pointer_address(
919fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      Isolate* isolate);
920fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org
921a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  static ExternalReference is_profiling_address(Isolate* isolate);
922a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  static ExternalReference invoke_function_callback(Isolate* isolate);
923a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  static ExternalReference invoke_accessor_getter_callback(Isolate* isolate);
924a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org
925d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  Address address() const { return reinterpret_cast<Address>(address_); }
92643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
92765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  // Function Debug::Break()
928ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  static ExternalReference debug_break(Isolate* isolate);
92965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
93065dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  // Used to check if single stepping is enabled in generated code.
931ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  static ExternalReference debug_step_in_fp_address(Isolate* isolate);
93265dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
933c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org#ifndef V8_INTERPRETED_REGEXP
93418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // C functions called from RegExp generated code.
93518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
93618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // Function NativeRegExpMacroAssembler::CaseInsensitiveCompareUC16()
937ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  static ExternalReference re_case_insensitive_compare_uc16(Isolate* isolate);
93818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
93918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // Function RegExpMacroAssembler*::CheckStackGuardState()
940ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  static ExternalReference re_check_stack_guard_state(Isolate* isolate);
94118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
94218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // Function NativeRegExpMacroAssembler::GrowStack()
943ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  static ExternalReference re_grow_stack(Isolate* isolate);
944b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
945b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // byte NativeRegExpMacroAssembler::word_character_bitmap
946b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  static ExternalReference re_word_character_map();
947b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
94818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#endif
94918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
950eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // This lets you register a function that rewrites all external references.
951eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Used by the ARM simulator to catch calls to external references.
9521c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  static void set_redirector(Isolate* isolate,
9531c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org                             ExternalReferenceRedirector* redirector) {
954ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    // We can't stack them.
955e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(isolate->external_reference_redirector() == NULL);
9561c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org    isolate->set_external_reference_redirector(
957ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        reinterpret_cast<ExternalReferenceRedirectorPointer*>(redirector));
958eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
959eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
960ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  static ExternalReference stress_deopt_count(Isolate* isolate);
961ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
962d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  bool operator==(const ExternalReference& other) const {
963d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return address_ == other.address_;
964d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
965d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
966d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  bool operator!=(const ExternalReference& other) const {
967d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return !(*this == other);
968d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
969d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
97043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
97143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  explicit ExternalReference(void* address)
972eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      : address_(address) {}
973eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
974ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  static void* Redirect(Isolate* isolate,
975ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                        Address address_arg,
97683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                        Type type = ExternalReference::BUILTIN_CALL) {
977ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    ExternalReferenceRedirector* redirector =
978ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        reinterpret_cast<ExternalReferenceRedirector*>(
979ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org            isolate->external_reference_redirector());
980eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    void* address = reinterpret_cast<void*>(address_arg);
981ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    void* answer = (redirector == NULL) ?
982c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org                   address :
983ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                   (*redirector)(address, type);
984c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org    return answer;
985eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
98643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
987eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  void* address_;
98843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
98943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
99043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
99143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// -----------------------------------------------------------------------------
992f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org// Position recording support
993f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
994a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgstruct PositionState {
995a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  PositionState() : current_position(RelocInfo::kNoPosition),
996a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                    written_position(RelocInfo::kNoPosition),
997a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                    current_statement_position(RelocInfo::kNoPosition),
998a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                    written_statement_position(RelocInfo::kNoPosition) {}
999a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1000a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int current_position;
1001a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int written_position;
1002a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1003a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int current_statement_position;
1004a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int written_statement_position;
1005a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
1006a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1007f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
1008f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.orgclass PositionsRecorder BASE_EMBEDDED {
1009f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org public:
1010f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  explicit PositionsRecorder(Assembler* assembler)
10110511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      : assembler_(assembler) {
1012c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    jit_handler_data_ = NULL;
10130511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  }
10140511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
1015c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  void AttachJITHandlerData(void* user_data) {
1016c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    jit_handler_data_ = user_data;
1017c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  }
1018a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1019c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  void* DetachJITHandlerData() {
1020c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    void* old_data = jit_handler_data_;
1021c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    jit_handler_data_ = NULL;
1022c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    return old_data;
1023c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  }
1024a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Set current position to pos.
1025a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void RecordPosition(int pos);
1026f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
1027f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  // Set current statement position to pos.
1028f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  void RecordStatementPosition(int pos);
1029f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
1030f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  // Write recorded positions to relocation information.
1031f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  bool WriteRecordedPositions();
1032f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
1033a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int current_position() const { return state_.current_position; }
1034f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
1035a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int current_statement_position() const {
1036a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return state_.current_statement_position;
1037a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1038f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
1039f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org private:
1040f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  Assembler* assembler_;
1041a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  PositionState state_;
1042f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
1043c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  // Currently jit_handler_data_ is used to store JITHandler-specific data
1044c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  // over the lifetime of a PositionsRecorder
1045c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  void* jit_handler_data_;
1046a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  friend class PreservePositionScope;
1047f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
1048a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  DISALLOW_COPY_AND_ASSIGN(PositionsRecorder);
1049f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org};
1050f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
1051f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
1052a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass PreservePositionScope BASE_EMBEDDED {
1053f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org public:
1054a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  explicit PreservePositionScope(PositionsRecorder* positions_recorder)
1055f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org      : positions_recorder_(positions_recorder),
1056a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        saved_state_(positions_recorder->state_) {}
1057f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
1058a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ~PreservePositionScope() {
1059a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    positions_recorder_->state_ = saved_state_;
1060f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  }
1061f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
1062f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org private:
1063f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  PositionsRecorder* positions_recorder_;
1064a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  const PositionState saved_state_;
1065a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1066a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  DISALLOW_COPY_AND_ASSIGN(PreservePositionScope);
1067f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org};
1068f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
1069f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org
1070f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org// -----------------------------------------------------------------------------
107143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Utility functions
107243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10731b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orginline int NumberOfBitsSet(uint32_t x) {
10745c838251403b0be9a882540f1922577abba4c872ager@chromium.org  unsigned int num_bits_set;
10755c838251403b0be9a882540f1922577abba4c872ager@chromium.org  for (num_bits_set = 0; x; x >>= 1) {
10765c838251403b0be9a882540f1922577abba4c872ager@chromium.org    num_bits_set += x & 1;
10775c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
10785c838251403b0be9a882540f1922577abba4c872ager@chromium.org  return num_bits_set;
10795c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
108043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1081394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.combool EvalComparison(Token::Value op, double op1, double op2);
1082394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
10835f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org// Computes pow(x, y) with the special cases in the spec for Math.pow.
10842e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgdouble power_helper(double x, double y);
10855f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgdouble power_double_int(double x, int y);
10865f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgdouble power_double_double(double x, double y);
10875f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
1088fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org// Helper class for generating code or data associated with the code
1089fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org// right after a call instruction. As an example this can be used to
1090fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org// generate safepoint data after calls for crankshaft.
1091fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.orgclass CallWrapper {
1092fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org public:
1093fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  CallWrapper() { }
1094fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  virtual ~CallWrapper() { }
1095fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  // Called just before emitting a call. Argument is the size of the generated
1096fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  // call code.
1097fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  virtual void BeforeCall(int call_size) const = 0;
1098fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  // Called just after emitting a call, i.e., at the return site for the call.
1099fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  virtual void AfterCall() const = 0;
1100fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org};
1101fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org
1102fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.orgclass NullCallWrapper : public CallWrapper {
1103fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org public:
1104fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  NullCallWrapper() { }
1105fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  virtual ~NullCallWrapper() { }
1106fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  virtual void BeforeCall(int call_size) const { }
1107fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  virtual void AfterCall() const { }
1108fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org};
1109fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org
1110bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org
111143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} }  // namespace v8::internal
111243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
111343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif  // V8_ASSEMBLER_H_
1114