Upgrade to 3.29
Update V8 to 3.29.88.17 and update makefiles to support building on
all the relevant platforms.
Bug: 17370214
Change-Id: Ia3407c157fd8d72a93e23d8318ccaf6ecf77fa4e
diff --git a/src/assembler.h b/src/assembler.h
index f960b58..3d2f7d9 100644
--- a/src/assembler.h
+++ b/src/assembler.h
@@ -35,14 +35,14 @@
#ifndef V8_ASSEMBLER_H_
#define V8_ASSEMBLER_H_
-#include "v8.h"
+#include "src/v8.h"
-#include "allocation.h"
-#include "builtins.h"
-#include "gdb-jit.h"
-#include "isolate.h"
-#include "runtime.h"
-#include "token.h"
+#include "src/allocation.h"
+#include "src/builtins.h"
+#include "src/gdb-jit.h"
+#include "src/isolate.h"
+#include "src/runtime.h"
+#include "src/token.h"
namespace v8 {
@@ -50,25 +50,163 @@
namespace internal {
-struct StatsCounter;
-const unsigned kNoASTId = -1;
+class StatsCounter;
// -----------------------------------------------------------------------------
// Platform independent assembler base class.
class AssemblerBase: public Malloced {
public:
- explicit AssemblerBase(Isolate* isolate);
+ AssemblerBase(Isolate* isolate, void* buffer, int buffer_size);
+ virtual ~AssemblerBase();
Isolate* isolate() const { return isolate_; }
- int jit_cookie() { return jit_cookie_; }
+ int jit_cookie() const { return jit_cookie_; }
+
+ bool emit_debug_code() const { return emit_debug_code_; }
+ void set_emit_debug_code(bool value) { emit_debug_code_ = value; }
+
+ bool serializer_enabled() const { return serializer_enabled_; }
+ void enable_serializer() { serializer_enabled_ = true; }
+
+ bool predictable_code_size() const { return predictable_code_size_; }
+ void set_predictable_code_size(bool value) { predictable_code_size_ = value; }
+
+ uint64_t enabled_cpu_features() const { return enabled_cpu_features_; }
+ void set_enabled_cpu_features(uint64_t features) {
+ enabled_cpu_features_ = features;
+ }
+ bool IsEnabled(CpuFeature f) {
+ return (enabled_cpu_features_ & (static_cast<uint64_t>(1) << f)) != 0;
+ }
// Overwrite a host NaN with a quiet target NaN. Used by mksnapshot for
// cross-snapshotting.
static void QuietNaN(HeapObject* nan) { }
+ int pc_offset() const { return static_cast<int>(pc_ - buffer_); }
+
+ // This function is called when code generation is aborted, so that
+ // the assembler could clean up internal data structures.
+ virtual void AbortedCodeGeneration() { }
+
+ static const int kMinimalBufferSize = 4*KB;
+
+ protected:
+ // The buffer into which code and relocation info are generated. It could
+ // either be owned by the assembler or be provided externally.
+ byte* buffer_;
+ int buffer_size_;
+ bool own_buffer_;
+
+ // The program counter, which points into the buffer above and moves forward.
+ byte* pc_;
+
private:
Isolate* isolate_;
int jit_cookie_;
+ uint64_t enabled_cpu_features_;
+ bool emit_debug_code_;
+ bool predictable_code_size_;
+ bool serializer_enabled_;
+};
+
+
+// Avoids emitting debug code during the lifetime of this scope object.
+class DontEmitDebugCodeScope BASE_EMBEDDED {
+ public:
+ explicit DontEmitDebugCodeScope(AssemblerBase* assembler)
+ : assembler_(assembler), old_value_(assembler->emit_debug_code()) {
+ assembler_->set_emit_debug_code(false);
+ }
+ ~DontEmitDebugCodeScope() {
+ assembler_->set_emit_debug_code(old_value_);
+ }
+ private:
+ AssemblerBase* assembler_;
+ bool old_value_;
+};
+
+
+// Avoids using instructions that vary in size in unpredictable ways between the
+// snapshot and the running VM.
+class PredictableCodeSizeScope {
+ public:
+ PredictableCodeSizeScope(AssemblerBase* assembler, int expected_size);
+ ~PredictableCodeSizeScope();
+
+ private:
+ AssemblerBase* assembler_;
+ int expected_size_;
+ int start_offset_;
+ bool old_value_;
+};
+
+
+// Enable a specified feature within a scope.
+class CpuFeatureScope BASE_EMBEDDED {
+ public:
+#ifdef DEBUG
+ CpuFeatureScope(AssemblerBase* assembler, CpuFeature f);
+ ~CpuFeatureScope();
+
+ private:
+ AssemblerBase* assembler_;
+ uint64_t old_enabled_;
+#else
+ CpuFeatureScope(AssemblerBase* assembler, CpuFeature f) {}
+#endif
+};
+
+
+// CpuFeatures keeps track of which features are supported by the target CPU.
+// Supported features must be enabled by a CpuFeatureScope before use.
+// Example:
+// if (assembler->IsSupported(SSE3)) {
+// CpuFeatureScope fscope(assembler, SSE3);
+// // Generate code containing SSE3 instructions.
+// } else {
+// // Generate alternative code.
+// }
+class CpuFeatures : public AllStatic {
+ public:
+ static void Probe(bool cross_compile) {
+ STATIC_ASSERT(NUMBER_OF_CPU_FEATURES <= kBitsPerInt);
+ if (initialized_) return;
+ initialized_ = true;
+ ProbeImpl(cross_compile);
+ }
+
+ static unsigned SupportedFeatures() {
+ Probe(false);
+ return supported_;
+ }
+
+ static bool IsSupported(CpuFeature f) {
+ return (supported_ & (1u << f)) != 0;
+ }
+
+ static inline bool SupportsCrankshaft();
+
+ static inline unsigned cache_line_size() {
+ DCHECK(cache_line_size_ != 0);
+ return cache_line_size_;
+ }
+
+ static void PrintTarget();
+ static void PrintFeatures();
+
+ // Flush instruction cache.
+ static void FlushICache(void* start, size_t size);
+
+ private:
+ // Platform-dependent implementation.
+ static void ProbeImpl(bool cross_compile);
+
+ static unsigned supported_;
+ static unsigned cache_line_size_;
+ static bool initialized_;
+ friend class ExternalReference;
+ DISALLOW_COPY_AND_ASSIGN(CpuFeatures);
};
@@ -90,8 +228,8 @@
}
INLINE(~Label()) {
- ASSERT(!is_linked());
- ASSERT(!is_near_linked());
+ DCHECK(!is_linked());
+ DCHECK(!is_near_linked());
}
INLINE(void Unuse()) { pos_ = 0; }
@@ -121,27 +259,38 @@
void bind_to(int pos) {
pos_ = -pos - 1;
- ASSERT(is_bound());
+ DCHECK(is_bound());
}
void link_to(int pos, Distance distance = kFar) {
if (distance == kNear) {
near_link_pos_ = pos + 1;
- ASSERT(is_near_linked());
+ DCHECK(is_near_linked());
} else {
pos_ = pos + 1;
- ASSERT(is_linked());
+ DCHECK(is_linked());
}
}
friend class Assembler;
- friend class RegexpAssembler;
friend class Displacement;
friend class RegExpMacroAssemblerIrregexp;
+
+#if V8_TARGET_ARCH_ARM64
+ // On ARM64, the Assembler keeps track of pointers to Labels to resolve
+ // branches to distant targets. Copying labels would confuse the Assembler.
+ DISALLOW_COPY_AND_ASSIGN(Label); // NOLINT
+#endif
};
enum SaveFPRegsMode { kDontSaveFPRegs, kSaveFPRegs };
+// Specifies whether to perform icache flush operations on RelocInfo updates.
+// If FLUSH_ICACHE_IF_NEEDED, the icache will always be flushed if an
+// instruction was modified. If SKIP_ICACHE_FLUSH the flush will always be
+// skipped (only use this if you will flush the icache manually before it is
+// executed).
+enum ICacheFlushMode { FLUSH_ICACHE_IF_NEEDED, SKIP_ICACHE_FLUSH };
// -----------------------------------------------------------------------------
// Relocation information
@@ -154,7 +303,7 @@
// describe a property of the datum. Such rmodes are useful for GC
// and nice disassembly output.
-class RelocInfo BASE_EMBEDDED {
+class RelocInfo {
public:
// The constant kNoPosition is used with the collecting of source positions
// in the relocation information. Two types of source positions are collected
@@ -189,10 +338,9 @@
CODE_TARGET, // Code target which is not any of the above.
CODE_TARGET_WITH_ID,
CONSTRUCT_CALL, // code target that is a call to a JavaScript constructor.
- CODE_TARGET_CONTEXT, // Code target used for contextual loads and stores.
DEBUG_BREAK, // Code target for the debugger statement.
EMBEDDED_OBJECT,
- GLOBAL_PROPERTY_CELL,
+ CELL,
// Everything after runtime_entry (inclusive) is not GC'ed.
RUNTIME_ENTRY,
@@ -204,23 +352,47 @@
EXTERNAL_REFERENCE, // The address of an external C++ function.
INTERNAL_REFERENCE, // An address inside the same function.
+ // Marks constant and veneer pools. Only used on ARM and ARM64.
+ // They use a custom noncompact encoding.
+ CONST_POOL,
+ VENEER_POOL,
+
// add more as needed
// Pseudo-types
- NUMBER_OF_MODES, // There are at most 14 modes with noncompact encoding.
- NONE, // never recorded
+ NUMBER_OF_MODES, // There are at most 15 modes with noncompact encoding.
+ NONE32, // never recorded 32-bit value
+ NONE64, // never recorded 64-bit value
+ CODE_AGE_SEQUENCE, // Not stored in RelocInfo array, used explictly by
+ // code aging.
+ FIRST_REAL_RELOC_MODE = CODE_TARGET,
+ LAST_REAL_RELOC_MODE = VENEER_POOL,
+ FIRST_PSEUDO_RELOC_MODE = CODE_AGE_SEQUENCE,
+ LAST_PSEUDO_RELOC_MODE = CODE_AGE_SEQUENCE,
LAST_CODE_ENUM = DEBUG_BREAK,
- LAST_GCED_ENUM = GLOBAL_PROPERTY_CELL,
+ LAST_GCED_ENUM = CELL,
// Modes <= LAST_COMPACT_ENUM are guaranteed to have compact encoding.
- LAST_COMPACT_ENUM = CODE_TARGET_WITH_ID
+ LAST_COMPACT_ENUM = CODE_TARGET_WITH_ID,
+ LAST_STANDARD_NONCOMPACT_ENUM = INTERNAL_REFERENCE
};
-
RelocInfo() {}
RelocInfo(byte* pc, Mode rmode, intptr_t data, Code* host)
: pc_(pc), rmode_(rmode), data_(data), host_(host) {
}
+ RelocInfo(byte* pc, double data64)
+ : pc_(pc), rmode_(NONE64), data64_(data64), host_(NULL) {
+ }
+ static inline bool IsRealRelocMode(Mode mode) {
+ return mode >= FIRST_REAL_RELOC_MODE &&
+ mode <= LAST_REAL_RELOC_MODE;
+ }
+ static inline bool IsPseudoRelocMode(Mode mode) {
+ DCHECK(!IsRealRelocMode(mode));
+ return mode >= FIRST_PSEUDO_RELOC_MODE &&
+ mode <= LAST_PSEUDO_RELOC_MODE;
+ }
static inline bool IsConstructCall(Mode mode) {
return mode == CONSTRUCT_CALL;
}
@@ -230,6 +402,9 @@
static inline bool IsEmbeddedObject(Mode mode) {
return mode == EMBEDDED_OBJECT;
}
+ static inline bool IsRuntimeEntry(Mode mode) {
+ return mode == RUNTIME_ENTRY;
+ }
// Is the relocation mode affected by GC?
static inline bool IsGCRelocMode(Mode mode) {
return mode <= LAST_GCED_ENUM;
@@ -240,6 +415,12 @@
static inline bool IsComment(Mode mode) {
return mode == COMMENT;
}
+ static inline bool IsConstPool(Mode mode) {
+ return mode == CONST_POOL;
+ }
+ static inline bool IsVeneerPool(Mode mode) {
+ return mode == VENEER_POOL;
+ }
static inline bool IsPosition(Mode mode) {
return mode == POSITION || mode == STATEMENT_POSITION;
}
@@ -255,39 +436,85 @@
static inline bool IsDebugBreakSlot(Mode mode) {
return mode == DEBUG_BREAK_SLOT;
}
+ static inline bool IsNone(Mode mode) {
+ return mode == NONE32 || mode == NONE64;
+ }
+ static inline bool IsCodeAgeSequence(Mode mode) {
+ return mode == CODE_AGE_SEQUENCE;
+ }
static inline int ModeMask(Mode mode) { return 1 << mode; }
+ // Returns true if the first RelocInfo has the same mode and raw data as the
+ // second one.
+ static inline bool IsEqual(RelocInfo first, RelocInfo second) {
+ return first.rmode() == second.rmode() &&
+ (first.rmode() == RelocInfo::NONE64 ?
+ first.raw_data64() == second.raw_data64() :
+ first.data() == second.data());
+ }
+
// Accessors
byte* pc() const { return pc_; }
void set_pc(byte* pc) { pc_ = pc; }
Mode rmode() const { return rmode_; }
intptr_t data() const { return data_; }
+ double data64() const { return data64_; }
+ uint64_t raw_data64() { return bit_cast<uint64_t>(data64_); }
Code* host() const { return host_; }
+ void set_host(Code* host) { host_ = host; }
// Apply a relocation by delta bytes
- INLINE(void apply(intptr_t delta));
+ INLINE(void apply(intptr_t delta,
+ ICacheFlushMode icache_flush_mode =
+ FLUSH_ICACHE_IF_NEEDED));
// Is the pointer this relocation info refers to coded like a plain pointer
// or is it strange in some way (e.g. relative or patched into a series of
// instructions).
bool IsCodedSpecially();
+ // If true, the pointer this relocation info refers to is an entry in the
+ // constant pool, otherwise the pointer is embedded in the instruction stream.
+ bool IsInConstantPool();
+
// Read/modify the code target in the branch/call instruction
// this relocation applies to;
- // can only be called if IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY
+ // can only be called if IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)
INLINE(Address target_address());
INLINE(void set_target_address(Address target,
- WriteBarrierMode mode = UPDATE_WRITE_BARRIER));
+ WriteBarrierMode write_barrier_mode =
+ UPDATE_WRITE_BARRIER,
+ ICacheFlushMode icache_flush_mode =
+ FLUSH_ICACHE_IF_NEEDED));
INLINE(Object* target_object());
INLINE(Handle<Object> target_object_handle(Assembler* origin));
- INLINE(Object** target_object_address());
INLINE(void set_target_object(Object* target,
- WriteBarrierMode mode = UPDATE_WRITE_BARRIER));
- INLINE(JSGlobalPropertyCell* target_cell());
- INLINE(Handle<JSGlobalPropertyCell> target_cell_handle());
- INLINE(void set_target_cell(JSGlobalPropertyCell* cell,
- WriteBarrierMode mode = UPDATE_WRITE_BARRIER));
+ WriteBarrierMode write_barrier_mode =
+ UPDATE_WRITE_BARRIER,
+ ICacheFlushMode icache_flush_mode =
+ FLUSH_ICACHE_IF_NEEDED));
+ INLINE(Address target_runtime_entry(Assembler* origin));
+ INLINE(void set_target_runtime_entry(Address target,
+ WriteBarrierMode write_barrier_mode =
+ UPDATE_WRITE_BARRIER,
+ ICacheFlushMode icache_flush_mode =
+ FLUSH_ICACHE_IF_NEEDED));
+ INLINE(Cell* target_cell());
+ INLINE(Handle<Cell> target_cell_handle());
+ INLINE(void set_target_cell(Cell* cell,
+ WriteBarrierMode write_barrier_mode =
+ UPDATE_WRITE_BARRIER,
+ ICacheFlushMode icache_flush_mode =
+ FLUSH_ICACHE_IF_NEEDED));
+ INLINE(Handle<Object> code_age_stub_handle(Assembler* origin));
+ INLINE(Code* code_age_stub());
+ INLINE(void set_code_age_stub(Code* stub,
+ ICacheFlushMode icache_flush_mode =
+ FLUSH_ICACHE_IF_NEEDED));
+ // Returns the address of the constant pool entry where the target address
+ // is held. This should only be called if IsInConstantPool returns true.
+ INLINE(Address constant_pool_entry_address());
// Read the address of the word containing the target_address in an
// instruction stream. What this means exactly is architecture-independent.
@@ -296,6 +523,7 @@
// output before the next target. Architecture-independent code shouldn't
// dereference the pointer it gets back from this.
INLINE(Address target_address_address());
+
// This indicates how much space a target takes up when deserializing a code
// stream. For most architectures this is just the size of a pointer. For
// an instruction like movw/movt where the target bits are mixed into the
@@ -309,7 +537,7 @@
// Read/modify the reference in the instruction this relocation
// applies to; can only be called if rmode_ is external_reference
- INLINE(Address* target_reference_address());
+ INLINE(Address target_reference());
// Read/modify the address of a call instruction. This is used to relocate
// the break points where straight-line code is patched with a call
@@ -320,8 +548,12 @@
INLINE(void set_call_object(Object* target));
INLINE(Object** call_object_address());
+ // Wipe out a relocation to a fixed value, used for making snapshots
+ // reproducible.
+ INLINE(void WipeOut());
+
template<typename StaticVisitor> inline void Visit(Heap* heap);
- inline void Visit(ObjectVisitor* v);
+ inline void Visit(Isolate* isolate, ObjectVisitor* v);
// Patch the code with some other code.
void PatchCode(byte* instructions, int instruction_count);
@@ -337,14 +569,19 @@
// debugger.
INLINE(bool IsPatchedDebugBreakSlotSequence());
+#ifdef DEBUG
+ // Check whether the given code contains relocation information that
+ // either is position-relative or movable by the garbage collector.
+ static bool RequiresRelocation(const CodeDesc& desc);
+#endif
+
#ifdef ENABLE_DISASSEMBLER
// Printing
static const char* RelocModeName(Mode rmode);
- void Print(FILE* out);
+ void Print(Isolate* isolate, OStream& os); // NOLINT
#endif // ENABLE_DISASSEMBLER
-#ifdef DEBUG
- // Debugging
- void Verify();
+#ifdef VERIFY_HEAP
+ void Verify(Isolate* isolate);
#endif
static const int kCodeTargetMask = (1 << (LAST_CODE_ENUM + 1)) - 1;
@@ -360,21 +597,16 @@
// comment).
byte* pc_;
Mode rmode_;
- intptr_t data_;
+ union {
+ intptr_t data_;
+ double data64_;
+ };
Code* host_;
-#ifdef V8_TARGET_ARCH_MIPS
- // Code and Embedded Object pointers in mips are stored split
- // across two consecutive 32-bit instructions. Heap management
- // routines expect to access these pointers indirectly. The following
- // location provides a place for these pointers to exist natually
- // when accessed via the Iterator.
- Object* reconstructed_obj_ptr_;
// External-reference pointers are also split across instruction-pairs
- // in mips, but are accessed via indirect pointers. This location
+ // on some platforms, but are accessed via indirect pointers. This location
// provides a place for that pointer to exist naturally. Its address
// is returned by RelocInfo::target_reference_address().
Address reconstructed_adr_ptr_;
-#endif // V8_TARGET_ARCH_MIPS
friend class RelocIterator;
};
@@ -416,6 +648,7 @@
inline void WriteTaggedPC(uint32_t pc_delta, int tag);
inline void WriteExtraTaggedPC(uint32_t pc_delta, int extra_tag);
inline void WriteExtraTaggedIntData(int data_delta, int top_tag);
+ inline void WriteExtraTaggedPoolData(int data, int pool_type);
inline void WriteExtraTaggedData(intptr_t data_delta, int top_tag);
inline void WriteTaggedData(intptr_t data_delta, int tag);
inline void WriteExtraTag(int extra_tag, int top_tag);
@@ -451,7 +684,7 @@
// Return pointer valid until next next().
RelocInfo* rinfo() {
- ASSERT(!done());
+ DCHECK(!done());
return &rinfo_;
}
@@ -466,6 +699,7 @@
void ReadTaggedPC();
void AdvanceReadPC();
void AdvanceReadId();
+ void AdvanceReadPoolData();
void AdvanceReadPosition();
void AdvanceReadData();
void AdvanceReadVariableLengthPCJump();
@@ -481,6 +715,7 @@
byte* pos_;
byte* end_;
+ byte* code_age_sequence_;
RelocInfo rinfo_;
bool done_;
int mode_mask_;
@@ -496,9 +731,7 @@
//----------------------------------------------------------------------------
class IC_Utility;
class SCTableReference;
-#ifdef ENABLE_DEBUGGER_SUPPORT
class Debug_Address;
-#endif
// An ExternalReference represents a C++ address used in the generated
@@ -511,7 +744,7 @@
// Used in the simulator to support different native api calls.
enum Type {
// Builtin call.
- // MaybeObject* f(v8::internal::Arguments).
+ // Object* f(v8::internal::Arguments).
BUILTIN_CALL, // default
// Builtin that takes float arguments and returns an int.
@@ -531,16 +764,31 @@
BUILTIN_FP_INT_CALL,
// Direct call to API function callback.
- // Handle<Value> f(v8::Arguments&)
+ // void f(v8::FunctionCallbackInfo&)
DIRECT_API_CALL,
+ // Call to function callback via InvokeFunctionCallback.
+ // void f(v8::FunctionCallbackInfo&, v8::FunctionCallback)
+ PROFILING_API_CALL,
+
// Direct call to accessor getter callback.
- // Handle<value> f(Local<String> property, AccessorInfo& info)
- DIRECT_GETTER_CALL
+ // void f(Local<Name> property, PropertyCallbackInfo& info)
+ DIRECT_GETTER_CALL,
+
+ // Call to accessor getter callback via InvokeAccessorGetterCallback.
+ // void f(Local<Name> property, PropertyCallbackInfo& info,
+ // AccessorNameGetterCallback callback)
+ PROFILING_GETTER_CALL
};
+ static void SetUp();
+ static void InitializeMathExpData();
+ static void TearDownMathExpData();
+
typedef void* ExternalReferenceRedirector(void* original, Type type);
+ ExternalReference() : address_(NULL) {}
+
ExternalReference(Builtins::CFunctionId id, Isolate* isolate);
ExternalReference(ApiFunction* ptr, Type type, Isolate* isolate);
@@ -553,18 +801,14 @@
ExternalReference(const IC_Utility& ic_utility, Isolate* isolate);
-#ifdef ENABLE_DEBUGGER_SUPPORT
- ExternalReference(const Debug_Address& debug_address, Isolate* isolate);
-#endif
-
explicit ExternalReference(StatsCounter* counter);
ExternalReference(Isolate::AddressId id, Isolate* isolate);
explicit ExternalReference(const SCTableReference& table_ref);
- // Isolate::Current() as an external reference.
- static ExternalReference isolate_address();
+ // Isolate as an external reference.
+ static ExternalReference isolate_address(Isolate* isolate);
// One-of-a-kind references. These references are not part of a general
// pattern. This means that they have to be added to the
@@ -572,25 +816,25 @@
static ExternalReference incremental_marking_record_write_function(
Isolate* isolate);
- static ExternalReference incremental_evacuation_record_write_function(
- Isolate* isolate);
static ExternalReference store_buffer_overflow_function(
Isolate* isolate);
static ExternalReference flush_icache_function(Isolate* isolate);
- static ExternalReference perform_gc_function(Isolate* isolate);
- static ExternalReference fill_heap_number_with_random_function(
- Isolate* isolate);
- static ExternalReference random_uint32_function(Isolate* isolate);
- static ExternalReference transcendental_cache_array_address(Isolate* isolate);
static ExternalReference delete_handle_scope_extensions(Isolate* isolate);
static ExternalReference get_date_field_function(Isolate* isolate);
static ExternalReference date_cache_stamp(Isolate* isolate);
+ static ExternalReference get_make_code_young_function(Isolate* isolate);
+ static ExternalReference get_mark_code_as_executed_function(Isolate* isolate);
+
// Deoptimization support.
static ExternalReference new_deoptimizer_function(Isolate* isolate);
static ExternalReference compute_output_frames_function(Isolate* isolate);
+ // Log support.
+ static ExternalReference log_enter_external_function(Isolate* isolate);
+ static ExternalReference log_leave_external_function(Isolate* isolate);
+
// Static data in the keyed lookup cache.
static ExternalReference keyed_lookup_cache_keys(Isolate* isolate);
static ExternalReference keyed_lookup_cache_field_offsets(Isolate* isolate);
@@ -598,6 +842,9 @@
// Static variable Heap::roots_array_start()
static ExternalReference roots_array_start(Isolate* isolate);
+ // Static variable Heap::allocation_sites_list_address()
+ static ExternalReference allocation_sites_list_address(Isolate* isolate);
+
// Static variable StackGuard::address_of_jslimit()
static ExternalReference address_of_stack_limit(Isolate* isolate);
@@ -617,8 +864,6 @@
// Static variable Heap::NewSpaceStart()
static ExternalReference new_space_start(Isolate* isolate);
static ExternalReference new_space_mask(Isolate* isolate);
- static ExternalReference heap_always_allocate_scope_depth(Isolate* isolate);
- static ExternalReference new_space_mark_bits(Isolate* isolate);
// Write barrier.
static ExternalReference store_buffer_top(Isolate* isolate);
@@ -626,43 +871,64 @@
// Used for fast allocation in generated code.
static ExternalReference new_space_allocation_top_address(Isolate* isolate);
static ExternalReference new_space_allocation_limit_address(Isolate* isolate);
+ static ExternalReference old_pointer_space_allocation_top_address(
+ Isolate* isolate);
+ static ExternalReference old_pointer_space_allocation_limit_address(
+ Isolate* isolate);
+ static ExternalReference old_data_space_allocation_top_address(
+ Isolate* isolate);
+ static ExternalReference old_data_space_allocation_limit_address(
+ Isolate* isolate);
- static ExternalReference double_fp_operation(Token::Value operation,
- Isolate* isolate);
- static ExternalReference compare_doubles(Isolate* isolate);
+ static ExternalReference mod_two_doubles_operation(Isolate* isolate);
static ExternalReference power_double_double_function(Isolate* isolate);
static ExternalReference power_double_int_function(Isolate* isolate);
- static ExternalReference handle_scope_next_address();
- static ExternalReference handle_scope_limit_address();
- static ExternalReference handle_scope_level_address();
+ static ExternalReference handle_scope_next_address(Isolate* isolate);
+ static ExternalReference handle_scope_limit_address(Isolate* isolate);
+ static ExternalReference handle_scope_level_address(Isolate* isolate);
static ExternalReference scheduled_exception_address(Isolate* isolate);
+ static ExternalReference address_of_pending_message_obj(Isolate* isolate);
+ static ExternalReference address_of_has_pending_message(Isolate* isolate);
+ static ExternalReference address_of_pending_message_script(Isolate* isolate);
// Static variables containing common double constants.
static ExternalReference address_of_min_int();
static ExternalReference address_of_one_half();
- static ExternalReference address_of_minus_zero();
- static ExternalReference address_of_zero();
- static ExternalReference address_of_uint8_max_value();
+ static ExternalReference address_of_minus_one_half();
static ExternalReference address_of_negative_infinity();
static ExternalReference address_of_canonical_non_hole_nan();
static ExternalReference address_of_the_hole_nan();
+ static ExternalReference address_of_uint32_bias();
- static ExternalReference math_sin_double_function(Isolate* isolate);
- static ExternalReference math_cos_double_function(Isolate* isolate);
- static ExternalReference math_tan_double_function(Isolate* isolate);
static ExternalReference math_log_double_function(Isolate* isolate);
- Address address() const {return reinterpret_cast<Address>(address_);}
+ static ExternalReference math_exp_constants(int constant_index);
+ static ExternalReference math_exp_log_table();
-#ifdef ENABLE_DEBUGGER_SUPPORT
+ static ExternalReference page_flags(Page* page);
+
+ static ExternalReference ForDeoptEntry(Address entry);
+
+ static ExternalReference cpu_features();
+
+ static ExternalReference debug_is_active_address(Isolate* isolate);
+ static ExternalReference debug_after_break_target_address(Isolate* isolate);
+ static ExternalReference debug_restarter_frame_function_pointer_address(
+ Isolate* isolate);
+
+ static ExternalReference is_profiling_address(Isolate* isolate);
+ static ExternalReference invoke_function_callback(Isolate* isolate);
+ static ExternalReference invoke_accessor_getter_callback(Isolate* isolate);
+
+ Address address() const { return reinterpret_cast<Address>(address_); }
+
// Function Debug::Break()
static ExternalReference debug_break(Isolate* isolate);
// Used to check if single stepping is enabled in generated code.
static ExternalReference debug_step_in_fp_address(Isolate* isolate);
-#endif
#ifndef V8_INTERPRETED_REGEXP
// C functions called from RegExp generated code.
@@ -686,27 +952,26 @@
static void set_redirector(Isolate* isolate,
ExternalReferenceRedirector* redirector) {
// We can't stack them.
- ASSERT(isolate->external_reference_redirector() == NULL);
+ DCHECK(isolate->external_reference_redirector() == NULL);
isolate->set_external_reference_redirector(
reinterpret_cast<ExternalReferenceRedirectorPointer*>(redirector));
}
+ static ExternalReference stress_deopt_count(Isolate* isolate);
+
+ bool operator==(const ExternalReference& other) const {
+ return address_ == other.address_;
+ }
+
+ bool operator!=(const ExternalReference& other) const {
+ return !(*this == other);
+ }
+
private:
explicit ExternalReference(void* address)
: address_(address) {}
static void* Redirect(Isolate* isolate,
- void* address,
- Type type = ExternalReference::BUILTIN_CALL) {
- ExternalReferenceRedirector* redirector =
- reinterpret_cast<ExternalReferenceRedirector*>(
- isolate->external_reference_redirector());
- if (redirector == NULL) return address;
- void* answer = (*redirector)(address, type);
- return answer;
- }
-
- static void* Redirect(Isolate* isolate,
Address address_arg,
Type type = ExternalReference::BUILTIN_CALL) {
ExternalReferenceRedirector* redirector =
@@ -744,29 +1009,18 @@
public:
explicit PositionsRecorder(Assembler* assembler)
: assembler_(assembler) {
-#ifdef ENABLE_GDB_JIT_INTERFACE
- gdbjit_lineinfo_ = NULL;
-#endif
+ jit_handler_data_ = NULL;
}
-#ifdef ENABLE_GDB_JIT_INTERFACE
- ~PositionsRecorder() {
- delete gdbjit_lineinfo_;
+ void AttachJITHandlerData(void* user_data) {
+ jit_handler_data_ = user_data;
}
- void StartGDBJITLineInfoRecording() {
- if (FLAG_gdbjit) {
- gdbjit_lineinfo_ = new GDBJITLineInfo();
- }
+ void* DetachJITHandlerData() {
+ void* old_data = jit_handler_data_;
+ jit_handler_data_ = NULL;
+ return old_data;
}
-
- GDBJITLineInfo* DetachGDBJITLineInfo() {
- GDBJITLineInfo* lineinfo = gdbjit_lineinfo_;
- gdbjit_lineinfo_ = NULL; // To prevent deallocation in destructor.
- return lineinfo;
- }
-#endif
-
// Set current position to pos.
void RecordPosition(int pos);
@@ -785,10 +1039,10 @@
private:
Assembler* assembler_;
PositionState state_;
-#ifdef ENABLE_GDB_JIT_INTERFACE
- GDBJITLineInfo* gdbjit_lineinfo_;
-#endif
+ // Currently jit_handler_data_ is used to store JITHandler-specific data
+ // over the lifetime of a PositionsRecorder
+ void* jit_handler_data_;
friend class PreservePositionScope;
DISALLOW_COPY_AND_ASSIGN(PositionsRecorder);
@@ -816,32 +1070,6 @@
// -----------------------------------------------------------------------------
// Utility functions
-inline bool is_intn(int x, int n) {
- return -(1 << (n-1)) <= x && x < (1 << (n-1));
-}
-
-inline bool is_int8(int x) { return is_intn(x, 8); }
-inline bool is_int16(int x) { return is_intn(x, 16); }
-inline bool is_int18(int x) { return is_intn(x, 18); }
-inline bool is_int24(int x) { return is_intn(x, 24); }
-
-inline bool is_uintn(int x, int n) {
- return (x & -(1 << n)) == 0;
-}
-
-inline bool is_uint2(int x) { return is_uintn(x, 2); }
-inline bool is_uint3(int x) { return is_uintn(x, 3); }
-inline bool is_uint4(int x) { return is_uintn(x, 4); }
-inline bool is_uint5(int x) { return is_uintn(x, 5); }
-inline bool is_uint6(int x) { return is_uintn(x, 6); }
-inline bool is_uint8(int x) { return is_uintn(x, 8); }
-inline bool is_uint10(int x) { return is_uintn(x, 10); }
-inline bool is_uint12(int x) { return is_uintn(x, 12); }
-inline bool is_uint16(int x) { return is_uintn(x, 16); }
-inline bool is_uint24(int x) { return is_uintn(x, 24); }
-inline bool is_uint26(int x) { return is_uintn(x, 26); }
-inline bool is_uint28(int x) { return is_uintn(x, 28); }
-
inline int NumberOfBitsSet(uint32_t x) {
unsigned int num_bits_set;
for (num_bits_set = 0; x; x >>= 1) {
@@ -853,6 +1081,7 @@
bool EvalComparison(Token::Value op, double op1, double op2);
// Computes pow(x, y) with the special cases in the spec for Math.pow.
+double power_helper(double x, double y);
double power_double_int(double x, int y);
double power_double_double(double x, double y);
@@ -878,6 +1107,7 @@
virtual void AfterCall() const { }
};
+
} } // namespace v8::internal
#endif // V8_ASSEMBLER_H_