diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2011-06-29 17:26:51 +0200 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2011-06-29 17:26:51 +0200 |
commit | 33af2720f26c2b25bc7f75ce7eb454ff99db6d35 (patch) | |
tree | 9a38f0c96420edf503eebd6325dd8d2d8249f653 /deps/v8/src/assembler.h | |
parent | 6afdca885adeeeed9eef8cbb01c3d97af0bc084d (diff) | |
download | node-new-33af2720f26c2b25bc7f75ce7eb454ff99db6d35.tar.gz |
Upgrade V8 to 3.4.8
Diffstat (limited to 'deps/v8/src/assembler.h')
-rw-r--r-- | deps/v8/src/assembler.h | 334 |
1 files changed, 203 insertions, 131 deletions
diff --git a/deps/v8/src/assembler.h b/deps/v8/src/assembler.h index 9b9eea6c80..bced11fec2 100644 --- a/deps/v8/src/assembler.h +++ b/deps/v8/src/assembler.h @@ -30,19 +30,34 @@ // The original source code covered by the above license above has been // modified significantly by Google Inc. -// Copyright 2006-2009 the V8 project authors. All rights reserved. +// Copyright 2011 the V8 project authors. All rights reserved. #ifndef V8_ASSEMBLER_H_ #define V8_ASSEMBLER_H_ +#include "allocation.h" #include "gdb-jit.h" #include "runtime.h" -#include "top.h" #include "token.h" namespace v8 { namespace internal { +const unsigned kNoASTId = -1; +// ----------------------------------------------------------------------------- +// Platform independent assembler base class. + +class AssemblerBase: public Malloced { + public: + explicit AssemblerBase(Isolate* isolate); + + Isolate* isolate() const { return isolate_; } + int jit_cookie() { return jit_cookie_; } + + private: + Isolate* isolate_; + int jit_cookie_; +}; // ----------------------------------------------------------------------------- // Common double constants. @@ -52,7 +67,10 @@ class DoubleConstant: public AllStatic { static const double min_int; static const double one_half; static const double minus_zero; + static const double zero; + static const double uint8_max_value; static const double negative_infinity; + static const double nan; }; @@ -64,18 +82,32 @@ class DoubleConstant: public AllStatic { class Label BASE_EMBEDDED { public: - INLINE(Label()) { Unuse(); } - INLINE(~Label()) { ASSERT(!is_linked()); } + enum Distance { + kNear, kFar + }; + + INLINE(Label()) { + Unuse(); + UnuseNear(); + } - INLINE(void Unuse()) { pos_ = 0; } + INLINE(~Label()) { + ASSERT(!is_linked()); + ASSERT(!is_near_linked()); + } - INLINE(bool is_bound() const) { return pos_ < 0; } - INLINE(bool is_unused() const) { return pos_ == 0; } - INLINE(bool is_linked() const) { return pos_ > 0; } + INLINE(void Unuse()) { pos_ = 0; } + INLINE(void UnuseNear()) { near_link_pos_ = 0; } + + INLINE(bool is_bound() const) { return pos_ < 0; } + INLINE(bool is_unused() const) { return pos_ == 0 && near_link_pos_ == 0; } + INLINE(bool is_linked() const) { return pos_ > 0; } + INLINE(bool is_near_linked() const) { return near_link_pos_ > 0; } // Returns the position of bound or linked labels. Cannot be used // for unused labels. int pos() const; + int near_link_pos() const { return near_link_pos_ - 1; } private: // pos_ encodes both the binding state (via its sign) @@ -86,75 +118,31 @@ class Label BASE_EMBEDDED { // pos_ > 0 linked label, pos() returns the last reference position int pos_; + // Behaves like |pos_| in the "> 0" case, but for near jumps to this label. + int near_link_pos_; + void bind_to(int pos) { pos_ = -pos - 1; ASSERT(is_bound()); } - void link_to(int pos) { - pos_ = pos + 1; - ASSERT(is_linked()); + void link_to(int pos, Distance distance = kFar) { + if (distance == kNear) { + near_link_pos_ = pos + 1; + ASSERT(is_near_linked()); + } else { + pos_ = pos + 1; + ASSERT(is_linked()); + } } friend class Assembler; friend class RegexpAssembler; friend class Displacement; - friend class ShadowTarget; friend class RegExpMacroAssemblerIrregexp; }; // ----------------------------------------------------------------------------- -// NearLabels are labels used for short jumps (in Intel jargon). -// NearLabels should be used if it can be guaranteed that the jump range is -// within -128 to +127. We already use short jumps when jumping backwards, -// so using a NearLabel will only have performance impact if used for forward -// jumps. -class NearLabel BASE_EMBEDDED { - public: - NearLabel() { Unuse(); } - ~NearLabel() { ASSERT(!is_linked()); } - - void Unuse() { - pos_ = -1; - unresolved_branches_ = 0; -#ifdef DEBUG - for (int i = 0; i < kMaxUnresolvedBranches; i++) { - unresolved_positions_[i] = -1; - } -#endif - } - - int pos() { - ASSERT(is_bound()); - return pos_; - } - - bool is_bound() { return pos_ >= 0; } - bool is_linked() { return !is_bound() && unresolved_branches_ > 0; } - bool is_unused() { return !is_bound() && unresolved_branches_ == 0; } - - void bind_to(int position) { - ASSERT(!is_bound()); - pos_ = position; - } - - void link_to(int position) { - ASSERT(!is_bound()); - ASSERT(unresolved_branches_ < kMaxUnresolvedBranches); - unresolved_positions_[unresolved_branches_++] = position; - } - - private: - static const int kMaxUnresolvedBranches = 8; - int pos_; - int unresolved_branches_; - int unresolved_positions_[kMaxUnresolvedBranches]; - - friend class Assembler; -}; - - -// ----------------------------------------------------------------------------- // Relocation information @@ -197,10 +185,11 @@ class RelocInfo BASE_EMBEDDED { enum Mode { // Please note the order is important (see IsCodeTarget, IsGCRelocMode). + 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. - CODE_TARGET, // Code target which is not any of the above. EMBEDDED_OBJECT, GLOBAL_PROPERTY_CELL, @@ -216,10 +205,12 @@ class RelocInfo BASE_EMBEDDED { // add more as needed // Pseudo-types - NUMBER_OF_MODES, // must be no greater than 14 - see RelocInfoWriter + NUMBER_OF_MODES, // There are at most 14 modes with noncompact encoding. NONE, // never recorded - LAST_CODE_ENUM = CODE_TARGET, - LAST_GCED_ENUM = GLOBAL_PROPERTY_CELL + LAST_CODE_ENUM = DEBUG_BREAK, + LAST_GCED_ENUM = GLOBAL_PROPERTY_CELL, + // Modes <= LAST_COMPACT_ENUM are guaranteed to have compact encoding. + LAST_COMPACT_ENUM = CODE_TARGET_WITH_ID }; @@ -320,7 +311,7 @@ class RelocInfo BASE_EMBEDDED { INLINE(void set_call_object(Object* target)); INLINE(Object** call_object_address()); - template<typename StaticVisitor> inline void Visit(); + template<typename StaticVisitor> inline void Visit(Heap* heap); inline void Visit(ObjectVisitor* v); // Patch the code with some other code. @@ -349,7 +340,8 @@ class RelocInfo BASE_EMBEDDED { static const int kCodeTargetMask = (1 << (LAST_CODE_ENUM + 1)) - 1; static const int kPositionMask = 1 << POSITION | 1 << STATEMENT_POSITION; - static const int kDebugMask = kPositionMask | 1 << COMMENT; + static const int kDataMask = + (1 << CODE_TARGET_WITH_ID) | kPositionMask | (1 << COMMENT); static const int kApplyMask; // Modes affected by apply. Depends on arch. private: @@ -360,6 +352,19 @@ class RelocInfo BASE_EMBEDDED { byte* pc_; Mode rmode_; intptr_t data_; +#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 + // 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; }; @@ -368,9 +373,14 @@ class RelocInfo BASE_EMBEDDED { // lower addresses. class RelocInfoWriter BASE_EMBEDDED { public: - RelocInfoWriter() : pos_(NULL), last_pc_(NULL), last_data_(0) {} - RelocInfoWriter(byte* pos, byte* pc) : pos_(pos), last_pc_(pc), - last_data_(0) {} + RelocInfoWriter() : pos_(NULL), + last_pc_(NULL), + last_id_(0), + last_position_(0) {} + RelocInfoWriter(byte* pos, byte* pc) : pos_(pos), + last_pc_(pc), + last_id_(0), + last_position_(0) {} byte* pos() const { return pos_; } byte* last_pc() const { return last_pc_; } @@ -395,13 +405,15 @@ class RelocInfoWriter BASE_EMBEDDED { inline uint32_t WriteVariableLengthPCJump(uint32_t pc_delta); 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 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); byte* pos_; byte* last_pc_; - intptr_t last_data_; + int last_id_; + int last_position_; DISALLOW_COPY_AND_ASSIGN(RelocInfoWriter); }; @@ -443,12 +455,13 @@ class RelocIterator: public Malloced { int GetTopTag(); void ReadTaggedPC(); void AdvanceReadPC(); + void AdvanceReadId(); + void AdvanceReadPosition(); void AdvanceReadData(); void AdvanceReadVariableLengthPCJump(); - int GetPositionTypeTag(); - void ReadTaggedData(); - - static RelocInfo::Mode DebugInfoModeFromTag(int tag); + int GetLocatableTypeTag(); + void ReadTaggedId(); + void ReadTaggedPosition(); // If the given mode is wanted, set it in rinfo_ and return true. // Else return false. Used for efficiently skipping unwanted modes. @@ -461,6 +474,8 @@ class RelocIterator: public Malloced { RelocInfo rinfo_; bool done_; int mode_mask_; + int last_id_; + int last_position_; DISALLOW_COPY_AND_ASSIGN(RelocIterator); }; @@ -489,9 +504,21 @@ class ExternalReference BASE_EMBEDDED { // MaybeObject* f(v8::internal::Arguments). BUILTIN_CALL, // default + // Builtin that takes float arguments and returns an int. + // int f(double, double). + BUILTIN_COMPARE_CALL, + // Builtin call that returns floating point. // double f(double, double). - FP_RETURN_CALL, + BUILTIN_FP_FP_CALL, + + // Builtin call that returns floating point. + // double f(double). + BUILTIN_FP_CALL, + + // Builtin call that returns floating point. + // double f(double, int). + BUILTIN_FP_INT_CALL, // Direct call to API function callback. // Handle<Value> f(v8::Arguments&) @@ -504,117 +531,131 @@ class ExternalReference BASE_EMBEDDED { typedef void* ExternalReferenceRedirector(void* original, Type type); - explicit ExternalReference(Builtins::CFunctionId id); + ExternalReference(Builtins::CFunctionId id, Isolate* isolate); - explicit ExternalReference(ApiFunction* ptr, Type type); + ExternalReference(ApiFunction* ptr, Type type, Isolate* isolate); - explicit ExternalReference(Builtins::Name name); + ExternalReference(Builtins::Name name, Isolate* isolate); - explicit ExternalReference(Runtime::FunctionId id); + ExternalReference(Runtime::FunctionId id, Isolate* isolate); - explicit ExternalReference(Runtime::Function* f); + ExternalReference(const Runtime::Function* f, Isolate* isolate); - explicit ExternalReference(const IC_Utility& ic_utility); + ExternalReference(const IC_Utility& ic_utility, Isolate* isolate); #ifdef ENABLE_DEBUGGER_SUPPORT - explicit ExternalReference(const Debug_Address& debug_address); + ExternalReference(const Debug_Address& debug_address, Isolate* isolate); #endif explicit ExternalReference(StatsCounter* counter); - explicit ExternalReference(Top::AddressId id); + ExternalReference(Isolate::AddressId id, Isolate* isolate); explicit ExternalReference(const SCTableReference& table_ref); + // Isolate::Current() as an external reference. + static ExternalReference isolate_address(); + // One-of-a-kind references. These references are not part of a general // pattern. This means that they have to be added to the // ExternalReferenceTable in serialize.cc manually. - static ExternalReference perform_gc_function(); - static ExternalReference fill_heap_number_with_random_function(); - static ExternalReference random_uint32_function(); - static ExternalReference transcendental_cache_array_address(); - static ExternalReference delete_handle_scope_extensions(); + 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); // Deoptimization support. - static ExternalReference new_deoptimizer_function(); - static ExternalReference compute_output_frames_function(); - static ExternalReference global_contexts_list(); + static ExternalReference new_deoptimizer_function(Isolate* isolate); + static ExternalReference compute_output_frames_function(Isolate* isolate); + static ExternalReference global_contexts_list(Isolate* isolate); // Static data in the keyed lookup cache. - static ExternalReference keyed_lookup_cache_keys(); - static ExternalReference keyed_lookup_cache_field_offsets(); + static ExternalReference keyed_lookup_cache_keys(Isolate* isolate); + static ExternalReference keyed_lookup_cache_field_offsets(Isolate* isolate); // Static variable Factory::the_hole_value.location() - static ExternalReference the_hole_value_location(); + static ExternalReference the_hole_value_location(Isolate* isolate); // Static variable Factory::arguments_marker.location() - static ExternalReference arguments_marker_location(); + static ExternalReference arguments_marker_location(Isolate* isolate); // Static variable Heap::roots_address() - static ExternalReference roots_address(); + static ExternalReference roots_address(Isolate* isolate); // Static variable StackGuard::address_of_jslimit() - static ExternalReference address_of_stack_limit(); + static ExternalReference address_of_stack_limit(Isolate* isolate); // Static variable StackGuard::address_of_real_jslimit() - static ExternalReference address_of_real_stack_limit(); + static ExternalReference address_of_real_stack_limit(Isolate* isolate); // Static variable RegExpStack::limit_address() - static ExternalReference address_of_regexp_stack_limit(); + static ExternalReference address_of_regexp_stack_limit(Isolate* isolate); // Static variables for RegExp. - static ExternalReference address_of_static_offsets_vector(); - static ExternalReference address_of_regexp_stack_memory_address(); - static ExternalReference address_of_regexp_stack_memory_size(); + static ExternalReference address_of_static_offsets_vector(Isolate* isolate); + static ExternalReference address_of_regexp_stack_memory_address( + Isolate* isolate); + static ExternalReference address_of_regexp_stack_memory_size( + Isolate* isolate); // Static variable Heap::NewSpaceStart() - static ExternalReference new_space_start(); - static ExternalReference new_space_mask(); - static ExternalReference heap_always_allocate_scope_depth(); + static ExternalReference new_space_start(Isolate* isolate); + static ExternalReference new_space_mask(Isolate* isolate); + static ExternalReference heap_always_allocate_scope_depth(Isolate* isolate); // Used for fast allocation in generated code. - static ExternalReference new_space_allocation_top_address(); - static ExternalReference new_space_allocation_limit_address(); + static ExternalReference new_space_allocation_top_address(Isolate* isolate); + static ExternalReference new_space_allocation_limit_address(Isolate* isolate); - static ExternalReference double_fp_operation(Token::Value operation); - static ExternalReference compare_doubles(); - static ExternalReference power_double_double_function(); - static ExternalReference power_double_int_function(); + static ExternalReference double_fp_operation(Token::Value operation, + Isolate* isolate); + static ExternalReference compare_doubles(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 scheduled_exception_address(); + static ExternalReference scheduled_exception_address(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_negative_infinity(); + static ExternalReference address_of_nan(); + + static ExternalReference math_sin_double_function(Isolate* isolate); + static ExternalReference math_cos_double_function(Isolate* isolate); + static ExternalReference math_log_double_function(Isolate* isolate); Address address() const {return reinterpret_cast<Address>(address_);} #ifdef ENABLE_DEBUGGER_SUPPORT // Function Debug::Break() - static ExternalReference 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(); + static ExternalReference debug_step_in_fp_address(Isolate* isolate); #endif #ifndef V8_INTERPRETED_REGEXP // C functions called from RegExp generated code. // Function NativeRegExpMacroAssembler::CaseInsensitiveCompareUC16() - static ExternalReference re_case_insensitive_compare_uc16(); + static ExternalReference re_case_insensitive_compare_uc16(Isolate* isolate); // Function RegExpMacroAssembler*::CheckStackGuardState() - static ExternalReference re_check_stack_guard_state(); + static ExternalReference re_check_stack_guard_state(Isolate* isolate); // Function NativeRegExpMacroAssembler::GrowStack() - static ExternalReference re_grow_stack(); + static ExternalReference re_grow_stack(Isolate* isolate); // byte NativeRegExpMacroAssembler::word_character_bitmap static ExternalReference re_word_character_map(); @@ -623,30 +664,39 @@ class ExternalReference BASE_EMBEDDED { // This lets you register a function that rewrites all external references. // Used by the ARM simulator to catch calls to external references. - static void set_redirector(ExternalReferenceRedirector* redirector) { - ASSERT(redirector_ == NULL); // We can't stack them. - redirector_ = redirector; + static void set_redirector(Isolate* isolate, + ExternalReferenceRedirector* redirector) { + // We can't stack them. + ASSERT(isolate->external_reference_redirector() == NULL); + isolate->set_external_reference_redirector( + reinterpret_cast<ExternalReferenceRedirectorPointer*>(redirector)); } private: explicit ExternalReference(void* address) : address_(address) {} - static ExternalReferenceRedirector* redirector_; - - static void* Redirect(void* address, + static void* Redirect(Isolate* isolate, + void* address, Type type = ExternalReference::BUILTIN_CALL) { - if (redirector_ == NULL) return address; - void* answer = (*redirector_)(address, type); + ExternalReferenceRedirector* redirector = + reinterpret_cast<ExternalReferenceRedirector*>( + isolate->external_reference_redirector()); + if (redirector == NULL) return address; + void* answer = (*redirector)(address, type); return answer; } - static void* Redirect(Address address_arg, + static void* Redirect(Isolate* isolate, + Address address_arg, Type type = ExternalReference::BUILTIN_CALL) { + ExternalReferenceRedirector* redirector = + reinterpret_cast<ExternalReferenceRedirector*>( + isolate->external_reference_redirector()); void* address = reinterpret_cast<void*>(address_arg); - void* answer = (redirector_ == NULL) ? + void* answer = (redirector == NULL) ? address : - (*redirector_)(address, type); + (*redirector)(address, type); return answer; } @@ -785,6 +835,28 @@ static inline int NumberOfBitsSet(uint32_t x) { double power_double_int(double x, int y); double power_double_double(double x, double y); +// Helper class for generating code or data associated with the code +// right after a call instruction. As an example this can be used to +// generate safepoint data after calls for crankshaft. +class CallWrapper { + public: + CallWrapper() { } + virtual ~CallWrapper() { } + // Called just before emitting a call. Argument is the size of the generated + // call code. + virtual void BeforeCall(int call_size) const = 0; + // Called just after emitting a call, i.e., at the return site for the call. + virtual void AfterCall() const = 0; +}; + +class NullCallWrapper : public CallWrapper { + public: + NullCallWrapper() { } + virtual ~NullCallWrapper() { } + virtual void BeforeCall(int call_size) const { } + virtual void AfterCall() const { } +}; + } } // namespace v8::internal #endif // V8_ASSEMBLER_H_ |