00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef V8_ASSEMBLER_H_
00036 #define V8_ASSEMBLER_H_
00037
00038 #include "runtime.h"
00039 #include "top.h"
00040 #include "zone-inl.h"
00041
00042 namespace v8 { namespace internal {
00043
00044
00045
00046
00047
00048
00049
00050
00051 class Label : public ZoneObject {
00052 public:
00053 INLINE(Label()) { Unuse(); }
00054 INLINE(~Label()) { ASSERT(!is_linked()); }
00055
00056 INLINE(void Unuse()) { pos_ = 0; }
00057
00058 INLINE(bool is_bound() const) { return pos_ < 0; }
00059 INLINE(bool is_unused() const) { return pos_ == 0; }
00060 INLINE(bool is_linked() const) { return pos_ > 0; }
00061
00062
00063
00064 int pos() const;
00065
00066 private:
00067
00068
00069
00070
00071
00072
00073 int pos_;
00074
00075 void bind_to(int pos) {
00076 pos_ = -pos - 1;
00077 ASSERT(is_bound());
00078 }
00079 void link_to(int pos) {
00080 pos_ = pos + 1;
00081 ASSERT(is_linked());
00082 }
00083
00084 friend class Assembler;
00085 friend class Displacement;
00086 friend class LabelShadow;
00087 };
00088
00089
00090
00091
00092
00093
00094
00095
00096 class LabelShadow : public Label {
00097 public:
00098 explicit LabelShadow(Label* original) {
00099 ASSERT(original != NULL);
00100 original_label_ = original;
00101 original_pos_ = original->pos_;
00102 original->Unuse();
00103 #ifdef DEBUG
00104 is_shadowing_ = true;
00105 #endif
00106 }
00107
00108 ~LabelShadow() {
00109 ASSERT(!is_shadowing_);
00110 }
00111
00112 void StopShadowing() {
00113 ASSERT(is_shadowing_ && is_unused());
00114 pos_ = original_label_->pos_;
00115 original_label_->pos_ = original_pos_;
00116 #ifdef DEBUG
00117 is_shadowing_ = false;
00118 #endif
00119 }
00120
00121 Label* original_label() const { return original_label_; }
00122
00123 private:
00124
00125
00126 Label* original_label_;
00127
00128
00129 int original_pos_;
00130
00131 #ifdef DEBUG
00132 bool is_shadowing_;
00133 #endif
00134 };
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148 class RelocInfo BASE_EMBEDDED {
00149 public:
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 static const int kNoPosition = -1;
00160
00161 enum Mode {
00162
00163 CONSTRUCT_CALL,
00164 CODE_TARGET_CONTEXT,
00165 CODE_TARGET,
00166 EMBEDDED_OBJECT,
00167 EMBEDDED_STRING,
00168
00169
00170 RUNTIME_ENTRY,
00171 JS_RETURN,
00172 COMMENT,
00173 POSITION,
00174 STATEMENT_POSITION,
00175 EXTERNAL_REFERENCE,
00176 INTERNAL_REFERENCE,
00177
00178
00179
00180 NUMBER_OF_MODES,
00181 NONE,
00182 LAST_CODE_ENUM = CODE_TARGET,
00183 LAST_GCED_ENUM = EMBEDDED_STRING
00184 };
00185
00186
00187 RelocInfo() {}
00188 RelocInfo(byte* pc, Mode rmode, intptr_t data)
00189 : pc_(pc), rmode_(rmode), data_(data) {
00190 }
00191
00192 static inline bool IsConstructCall(Mode mode) {
00193 return mode == CONSTRUCT_CALL;
00194 }
00195 static inline bool IsCodeTarget(Mode mode) {
00196 return mode <= LAST_CODE_ENUM;
00197 }
00198
00199 static inline bool IsGCRelocMode(Mode mode) {
00200 return mode <= LAST_GCED_ENUM;
00201 }
00202 static inline bool IsJSReturn(Mode mode) {
00203 return mode == JS_RETURN;
00204 }
00205 static inline bool IsComment(Mode mode) {
00206 return mode == COMMENT;
00207 }
00208 static inline bool IsPosition(Mode mode) {
00209 return mode == POSITION || mode == STATEMENT_POSITION;
00210 }
00211 static inline bool IsStatementPosition(Mode mode) {
00212 return mode == STATEMENT_POSITION;
00213 }
00214 static inline bool IsExternalReference(Mode mode) {
00215 return mode == EXTERNAL_REFERENCE;
00216 }
00217 static inline bool IsInternalReference(Mode mode) {
00218 return mode == INTERNAL_REFERENCE;
00219 }
00220 static inline int ModeMask(Mode mode) { return 1 << mode; }
00221
00222
00223 byte* pc() const { return pc_; }
00224 void set_pc(byte* pc) { pc_ = pc; }
00225 Mode rmode() const { return rmode_; }
00226 intptr_t data() const { return data_; }
00227
00228
00229 INLINE(void apply(int delta));
00230
00231
00232
00233 INLINE(Address target_address());
00234 INLINE(void set_target_address(Address target));
00235 INLINE(Object* target_object());
00236 INLINE(Object** target_object_address());
00237 INLINE(void set_target_object(Object* target));
00238
00239
00240
00241 INLINE(Address* target_reference_address());
00242
00243
00244
00245
00246 INLINE(Address call_address());
00247 INLINE(void set_call_address(Address target));
00248 INLINE(Object* call_object());
00249 INLINE(Object** call_object_address());
00250 INLINE(void set_call_object(Object* target));
00251
00252
00253 void patch_code(byte* instructions, int instruction_count);
00254
00255
00256 void patch_code_with_call(Address target, int guard_bytes);
00257 INLINE(bool is_call_instruction());
00258
00259 #ifdef ENABLE_DISASSEMBLER
00260
00261 static const char* RelocModeName(Mode rmode);
00262 void Print();
00263 #endif // ENABLE_DISASSEMBLER
00264 #ifdef DEBUG
00265
00266 void Verify();
00267 #endif
00268
00269 static const int kCodeTargetMask = (1 << (LAST_CODE_ENUM + 1)) - 1;
00270 static const int kPositionMask = 1 << POSITION | 1 << STATEMENT_POSITION;
00271 static const int kDebugMask = kPositionMask | 1 << COMMENT;
00272 static const int kApplyMask;
00273
00274 private:
00275
00276
00277
00278
00279 byte* pc_;
00280 Mode rmode_;
00281 intptr_t data_;
00282 friend class RelocIterator;
00283 };
00284
00285
00286
00287
00288 class RelocInfoWriter BASE_EMBEDDED {
00289 public:
00290 RelocInfoWriter() : pos_(NULL), last_pc_(NULL), last_data_(0) {}
00291 RelocInfoWriter(byte* pos, byte* pc) : pos_(pos), last_pc_(pc),
00292 last_data_(0) {}
00293
00294 byte* pos() const { return pos_; }
00295 byte* last_pc() const { return last_pc_; }
00296
00297 void Write(const RelocInfo* rinfo);
00298
00299
00300
00301 void Reposition(byte* pos, byte* pc) {
00302 pos_ = pos;
00303 last_pc_ = pc;
00304 }
00305
00306
00307 static const int kMaxSize = 12;
00308
00309 private:
00310 inline uint32_t WriteVariableLengthPCJump(uint32_t pc_delta);
00311 inline void WriteTaggedPC(uint32_t pc_delta, int tag);
00312 inline void WriteExtraTaggedPC(uint32_t pc_delta, int extra_tag);
00313 inline void WriteExtraTaggedData(int32_t data_delta, int top_tag);
00314 inline void WriteTaggedData(int32_t data_delta, int tag);
00315 inline void WriteExtraTag(int extra_tag, int top_tag);
00316
00317 byte* pos_;
00318 byte* last_pc_;
00319 intptr_t last_data_;
00320 DISALLOW_COPY_AND_ASSIGN(RelocInfoWriter);
00321 };
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332 class RelocIterator: public Malloced {
00333 public:
00334
00335
00336
00337
00338 explicit RelocIterator(Code* code, int mode_mask = -1);
00339 explicit RelocIterator(const CodeDesc& desc, int mode_mask = -1);
00340
00341
00342 bool done() const { return done_; }
00343 void next();
00344
00345
00346 RelocInfo* rinfo() {
00347 ASSERT(!done());
00348 return &rinfo_;
00349 }
00350
00351 private:
00352
00353
00354
00355 void Advance(int bytes = 1) { pos_ -= bytes; }
00356 int AdvanceGetTag();
00357 int GetExtraTag();
00358 int GetTopTag();
00359 void ReadTaggedPC();
00360 void AdvanceReadPC();
00361 void AdvanceReadData();
00362 void AdvanceReadVariableLengthPCJump();
00363 int GetPositionTypeTag();
00364 void ReadTaggedData();
00365
00366 static RelocInfo::Mode DebugInfoModeFromTag(int tag);
00367
00368
00369
00370 bool SetMode(RelocInfo::Mode mode) {
00371 return (mode_mask_ & 1 << mode) ? (rinfo_.rmode_ = mode, true) : false;
00372 }
00373
00374 byte* pos_;
00375 byte* end_;
00376 RelocInfo rinfo_;
00377 bool done_;
00378 int mode_mask_;
00379 DISALLOW_COPY_AND_ASSIGN(RelocIterator);
00380 };
00381
00382
00383
00384
00385
00386
00387 class IC_Utility;
00388 class Debug_Address;
00389 class SCTableReference;
00390
00391
00392
00393
00394
00395 class ExternalReference BASE_EMBEDDED {
00396 public:
00397 explicit ExternalReference(Builtins::CFunctionId id);
00398
00399 explicit ExternalReference(Builtins::Name name);
00400
00401 explicit ExternalReference(Runtime::FunctionId id);
00402
00403 explicit ExternalReference(Runtime::Function* f);
00404
00405 explicit ExternalReference(const IC_Utility& ic_utility);
00406
00407 explicit ExternalReference(const Debug_Address& debug_address);
00408
00409 explicit ExternalReference(StatsCounter* counter);
00410
00411 explicit ExternalReference(Top::AddressId id);
00412
00413 explicit ExternalReference(const SCTableReference& table_ref);
00414
00415
00416
00417
00418
00419 static ExternalReference builtin_passed_function();
00420
00421
00422 static ExternalReference the_hole_value_location();
00423
00424
00425 static ExternalReference address_of_stack_guard_limit();
00426
00427
00428 static ExternalReference debug_break();
00429
00430
00431 static ExternalReference new_space_start();
00432 static ExternalReference heap_always_allocate_scope_depth();
00433
00434
00435 static ExternalReference new_space_allocation_top_address();
00436 static ExternalReference new_space_allocation_limit_address();
00437
00438
00439 static ExternalReference debug_step_in_fp_address();
00440
00441 Address address() const {return address_;}
00442
00443 private:
00444 explicit ExternalReference(void* address)
00445 : address_(reinterpret_cast<Address>(address)) {}
00446
00447 Address address_;
00448 };
00449
00450
00451
00452
00453
00454
00455
00456 static inline bool is_intn(int x, int n) {
00457 return -(1 << (n-1)) <= x && x < (1 << (n-1));
00458 }
00459
00460 static inline bool is_int24(int x) { return is_intn(x, 24); }
00461 static inline bool is_int8(int x) { return is_intn(x, 8); }
00462
00463 static inline bool is_uintn(int x, int n) {
00464 return (x & -(1 << n)) == 0;
00465 }
00466
00467 static inline bool is_uint3(int x) { return is_uintn(x, 3); }
00468 static inline bool is_uint4(int x) { return is_uintn(x, 4); }
00469 static inline bool is_uint5(int x) { return is_uintn(x, 5); }
00470 static inline bool is_uint8(int x) { return is_uintn(x, 8); }
00471 static inline bool is_uint12(int x) { return is_uintn(x, 12); }
00472 static inline bool is_uint16(int x) { return is_uintn(x, 16); }
00473 static inline bool is_uint24(int x) { return is_uintn(x, 24); }
00474
00475 } }
00476
00477 #endif // V8_ASSEMBLER_H_