v8  3.14.5(node0.10.28)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
assembler.cc
Go to the documentation of this file.
1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
2 // All Rights Reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // - Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 //
11 // - Redistribution in binary form must reproduce the above copyright
12 // notice, this list of conditions and the following disclaimer in the
13 // documentation and/or other materials provided with the distribution.
14 //
15 // - Neither the name of Sun Microsystems or the names of contributors may
16 // be used to endorse or promote products derived from this software without
17 // specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20 // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 // The original source code covered by the above license above has been
32 // modified significantly by Google Inc.
33 // Copyright 2012 the V8 project authors. All rights reserved.
34 
35 #include "assembler.h"
36 
37 #include <math.h> // For cos, log, pow, sin, tan, etc.
38 #include "api.h"
39 #include "builtins.h"
40 #include "counters.h"
41 #include "cpu.h"
42 #include "debug.h"
43 #include "deoptimizer.h"
44 #include "execution.h"
45 #include "ic.h"
46 #include "isolate.h"
47 #include "jsregexp.h"
48 #include "lazy-instance.h"
49 #include "platform.h"
50 #include "regexp-macro-assembler.h"
51 #include "regexp-stack.h"
52 #include "runtime.h"
53 #include "serialize.h"
54 #include "store-buffer-inl.h"
55 #include "stub-cache.h"
56 #include "token.h"
57 
58 #if V8_TARGET_ARCH_IA32
60 #elif V8_TARGET_ARCH_X64
61 #include "x64/assembler-x64-inl.h"
62 #elif V8_TARGET_ARCH_ARM
63 #include "arm/assembler-arm-inl.h"
64 #elif V8_TARGET_ARCH_MIPS
66 #else
67 #error "Unknown architecture."
68 #endif
69 
70 // Include native regexp-macro-assembler.
71 #ifndef V8_INTERPRETED_REGEXP
72 #if V8_TARGET_ARCH_IA32
74 #elif V8_TARGET_ARCH_X64
76 #elif V8_TARGET_ARCH_ARM
78 #elif V8_TARGET_ARCH_MIPS
80 #else // Unknown architecture.
81 #error "Unknown architecture."
82 #endif // Target architecture.
83 #endif // V8_INTERPRETED_REGEXP
84 
85 namespace v8 {
86 namespace internal {
87 
88 // -----------------------------------------------------------------------------
89 // Common double constants.
90 
91 struct DoubleConstant BASE_EMBEDDED {
92  double min_int;
93  double one_half;
94  double minus_zero;
95  double zero;
99  double the_hole_nan;
100 };
101 
102 static DoubleConstant double_constants;
103 
104 const char* const RelocInfo::kFillerCommentString = "DEOPTIMIZATION PADDING";
105 
106 // -----------------------------------------------------------------------------
107 // Implementation of AssemblerBase
108 
110  : isolate_(isolate),
111  jit_cookie_(0) {
112  if (FLAG_mask_constants_with_cookie && isolate != NULL) {
113  jit_cookie_ = V8::RandomPrivate(isolate);
114  }
115 }
116 
117 
118 // -----------------------------------------------------------------------------
119 // Implementation of Label
120 
121 int Label::pos() const {
122  if (pos_ < 0) return -pos_ - 1;
123  if (pos_ > 0) return pos_ - 1;
124  UNREACHABLE();
125  return 0;
126 }
127 
128 
129 // -----------------------------------------------------------------------------
130 // Implementation of RelocInfoWriter and RelocIterator
131 //
132 // Relocation information is written backwards in memory, from high addresses
133 // towards low addresses, byte by byte. Therefore, in the encodings listed
134 // below, the first byte listed it at the highest address, and successive
135 // bytes in the record are at progressively lower addresses.
136 //
137 // Encoding
138 //
139 // The most common modes are given single-byte encodings. Also, it is
140 // easy to identify the type of reloc info and skip unwanted modes in
141 // an iteration.
142 //
143 // The encoding relies on the fact that there are fewer than 14
144 // different relocation modes using standard non-compact encoding.
145 //
146 // The first byte of a relocation record has a tag in its low 2 bits:
147 // Here are the record schemes, depending on the low tag and optional higher
148 // tags.
149 //
150 // Low tag:
151 // 00: embedded_object: [6-bit pc delta] 00
152 //
153 // 01: code_target: [6-bit pc delta] 01
154 //
155 // 10: short_data_record: [6-bit pc delta] 10 followed by
156 // [6-bit data delta] [2-bit data type tag]
157 //
158 // 11: long_record [2-bit high tag][4 bit middle_tag] 11
159 // followed by variable data depending on type.
160 //
161 // 2-bit data type tags, used in short_data_record and data_jump long_record:
162 // code_target_with_id: 00
163 // position: 01
164 // statement_position: 10
165 // comment: 11 (not used in short_data_record)
166 //
167 // Long record format:
168 // 4-bit middle_tag:
169 // 0000 - 1100 : Short record for RelocInfo::Mode middle_tag + 2
170 // (The middle_tag encodes rmode - RelocInfo::LAST_COMPACT_ENUM,
171 // and is between 0000 and 1100)
172 // The format is:
173 // 00 [4 bit middle_tag] 11 followed by
174 // 00 [6 bit pc delta]
175 //
176 // 1101: constant pool. Used on ARM only for now.
177 // The format is: 11 1101 11
178 // signed int (size of the constant pool).
179 // 1110: long_data_record
180 // The format is: [2-bit data_type_tag] 1110 11
181 // signed intptr_t, lowest byte written first
182 // (except data_type code_target_with_id, which
183 // is followed by a signed int, not intptr_t.)
184 //
185 // 1111: long_pc_jump
186 // The format is:
187 // pc-jump: 00 1111 11,
188 // 00 [6 bits pc delta]
189 // or
190 // pc-jump (variable length):
191 // 01 1111 11,
192 // [7 bits data] 0
193 // ...
194 // [7 bits data] 1
195 // (Bits 6..31 of pc delta, with leading zeroes
196 // dropped, and last non-zero chunk tagged with 1.)
197 
198 
200 
201 const int kTagBits = 2;
202 const int kTagMask = (1 << kTagBits) - 1;
203 const int kExtraTagBits = 4;
204 const int kLocatableTypeTagBits = 2;
206 
207 const int kEmbeddedObjectTag = 0;
208 const int kCodeTargetTag = 1;
209 const int kLocatableTag = 2;
210 const int kDefaultTag = 3;
211 
212 const int kPCJumpExtraTag = (1 << kExtraTagBits) - 1;
213 
215 const int kSmallPCDeltaMask = (1 << kSmallPCDeltaBits) - 1;
216 const int RelocInfo::kMaxSmallPCDelta = kSmallPCDeltaMask;
217 
219 const int kChunkBits = 7;
220 const int kChunkMask = (1 << kChunkBits) - 1;
221 const int kLastChunkTagBits = 1;
222 const int kLastChunkTagMask = 1;
223 const int kLastChunkTag = 1;
224 
225 
227 
228 const int kCodeWithIdTag = 0;
230 const int kStatementPositionTag = 2;
231 const int kCommentTag = 3;
232 
234 const int kConstPoolTag = 3;
235 
236 
237 uint32_t RelocInfoWriter::WriteVariableLengthPCJump(uint32_t pc_delta) {
238  // Return if the pc_delta can fit in kSmallPCDeltaBits bits.
239  // Otherwise write a variable length PC jump for the bits that do
240  // not fit in the kSmallPCDeltaBits bits.
241  if (is_uintn(pc_delta, kSmallPCDeltaBits)) return pc_delta;
243  uint32_t pc_jump = pc_delta >> kSmallPCDeltaBits;
244  ASSERT(pc_jump > 0);
245  // Write kChunkBits size chunks of the pc_jump.
246  for (; pc_jump > 0; pc_jump = pc_jump >> kChunkBits) {
247  byte b = pc_jump & kChunkMask;
248  *--pos_ = b << kLastChunkTagBits;
249  }
250  // Tag the last chunk so it can be identified.
251  *pos_ = *pos_ | kLastChunkTag;
252  // Return the remaining kSmallPCDeltaBits of the pc_delta.
253  return pc_delta & kSmallPCDeltaMask;
254 }
255 
256 
257 void RelocInfoWriter::WriteTaggedPC(uint32_t pc_delta, int tag) {
258  // Write a byte of tagged pc-delta, possibly preceded by var. length pc-jump.
259  pc_delta = WriteVariableLengthPCJump(pc_delta);
260  *--pos_ = pc_delta << kTagBits | tag;
261 }
262 
263 
264 void RelocInfoWriter::WriteTaggedData(intptr_t data_delta, int tag) {
265  *--pos_ = static_cast<byte>(data_delta << kLocatableTypeTagBits | tag);
266 }
267 
268 
269 void RelocInfoWriter::WriteExtraTag(int extra_tag, int top_tag) {
270  *--pos_ = static_cast<int>(top_tag << (kTagBits + kExtraTagBits) |
271  extra_tag << kTagBits |
272  kDefaultTag);
273 }
274 
275 
276 void RelocInfoWriter::WriteExtraTaggedPC(uint32_t pc_delta, int extra_tag) {
277  // Write two-byte tagged pc-delta, possibly preceded by var. length pc-jump.
278  pc_delta = WriteVariableLengthPCJump(pc_delta);
279  WriteExtraTag(extra_tag, 0);
280  *--pos_ = pc_delta;
281 }
282 
283 
284 void RelocInfoWriter::WriteExtraTaggedIntData(int data_delta, int top_tag) {
285  WriteExtraTag(kDataJumpExtraTag, top_tag);
286  for (int i = 0; i < kIntSize; i++) {
287  *--pos_ = static_cast<byte>(data_delta);
288  // Signed right shift is arithmetic shift. Tested in test-utils.cc.
289  data_delta = data_delta >> kBitsPerByte;
290  }
291 }
292 
293 void RelocInfoWriter::WriteExtraTaggedConstPoolData(int data) {
294  WriteExtraTag(kConstPoolExtraTag, kConstPoolTag);
295  for (int i = 0; i < kIntSize; i++) {
296  *--pos_ = static_cast<byte>(data);
297  // Signed right shift is arithmetic shift. Tested in test-utils.cc.
298  data = data >> kBitsPerByte;
299  }
300 }
301 
302 void RelocInfoWriter::WriteExtraTaggedData(intptr_t data_delta, int top_tag) {
303  WriteExtraTag(kDataJumpExtraTag, top_tag);
304  for (int i = 0; i < kIntptrSize; i++) {
305  *--pos_ = static_cast<byte>(data_delta);
306  // Signed right shift is arithmetic shift. Tested in test-utils.cc.
307  data_delta = data_delta >> kBitsPerByte;
308  }
309 }
310 
311 
312 void RelocInfoWriter::Write(const RelocInfo* rinfo) {
313 #ifdef DEBUG
314  byte* begin_pos = pos_;
315 #endif
316  ASSERT(rinfo->pc() - last_pc_ >= 0);
317  ASSERT(RelocInfo::LAST_STANDARD_NONCOMPACT_ENUM - RelocInfo::LAST_COMPACT_ENUM
319  // Use unsigned delta-encoding for pc.
320  uint32_t pc_delta = static_cast<uint32_t>(rinfo->pc() - last_pc_);
321  RelocInfo::Mode rmode = rinfo->rmode();
322 
323  // The two most common modes are given small tags, and usually fit in a byte.
324  if (rmode == RelocInfo::EMBEDDED_OBJECT) {
325  WriteTaggedPC(pc_delta, kEmbeddedObjectTag);
326  } else if (rmode == RelocInfo::CODE_TARGET) {
327  WriteTaggedPC(pc_delta, kCodeTargetTag);
328  ASSERT(begin_pos - pos_ <= RelocInfo::kMaxCallSize);
329  } else if (rmode == RelocInfo::CODE_TARGET_WITH_ID) {
330  // Use signed delta-encoding for id.
331  ASSERT(static_cast<int>(rinfo->data()) == rinfo->data());
332  int id_delta = static_cast<int>(rinfo->data()) - last_id_;
333  // Check if delta is small enough to fit in a tagged byte.
334  if (is_intn(id_delta, kSmallDataBits)) {
335  WriteTaggedPC(pc_delta, kLocatableTag);
336  WriteTaggedData(id_delta, kCodeWithIdTag);
337  } else {
338  // Otherwise, use costly encoding.
339  WriteExtraTaggedPC(pc_delta, kPCJumpExtraTag);
340  WriteExtraTaggedIntData(id_delta, kCodeWithIdTag);
341  }
342  last_id_ = static_cast<int>(rinfo->data());
343  } else if (RelocInfo::IsPosition(rmode)) {
344  // Use signed delta-encoding for position.
345  ASSERT(static_cast<int>(rinfo->data()) == rinfo->data());
346  int pos_delta = static_cast<int>(rinfo->data()) - last_position_;
347  int pos_type_tag = (rmode == RelocInfo::POSITION) ? kNonstatementPositionTag
349  // Check if delta is small enough to fit in a tagged byte.
350  if (is_intn(pos_delta, kSmallDataBits)) {
351  WriteTaggedPC(pc_delta, kLocatableTag);
352  WriteTaggedData(pos_delta, pos_type_tag);
353  } else {
354  // Otherwise, use costly encoding.
355  WriteExtraTaggedPC(pc_delta, kPCJumpExtraTag);
356  WriteExtraTaggedIntData(pos_delta, pos_type_tag);
357  }
358  last_position_ = static_cast<int>(rinfo->data());
359  } else if (RelocInfo::IsComment(rmode)) {
360  // Comments are normally not generated, so we use the costly encoding.
361  WriteExtraTaggedPC(pc_delta, kPCJumpExtraTag);
362  WriteExtraTaggedData(rinfo->data(), kCommentTag);
363  ASSERT(begin_pos - pos_ >= RelocInfo::kMinRelocCommentSize);
364  } else if (RelocInfo::IsConstPool(rmode)) {
365  WriteExtraTaggedPC(pc_delta, kPCJumpExtraTag);
366  WriteExtraTaggedConstPoolData(static_cast<int>(rinfo->data()));
367  } else {
368  ASSERT(rmode > RelocInfo::LAST_COMPACT_ENUM);
369  int saved_mode = rmode - RelocInfo::LAST_COMPACT_ENUM;
370  // For all other modes we simply use the mode as the extra tag.
371  // None of these modes need a data component.
372  ASSERT(saved_mode < kPCJumpExtraTag && saved_mode < kDataJumpExtraTag);
373  WriteExtraTaggedPC(pc_delta, saved_mode);
374  }
375  last_pc_ = rinfo->pc();
376 #ifdef DEBUG
377  ASSERT(begin_pos - pos_ <= kMaxSize);
378 #endif
379 }
380 
381 
382 inline int RelocIterator::AdvanceGetTag() {
383  return *--pos_ & kTagMask;
384 }
385 
386 
387 inline int RelocIterator::GetExtraTag() {
388  return (*pos_ >> kTagBits) & ((1 << kExtraTagBits) - 1);
389 }
390 
391 
392 inline int RelocIterator::GetTopTag() {
393  return *pos_ >> (kTagBits + kExtraTagBits);
394 }
395 
396 
397 inline void RelocIterator::ReadTaggedPC() {
398  rinfo_.pc_ += *pos_ >> kTagBits;
399 }
400 
401 
402 inline void RelocIterator::AdvanceReadPC() {
403  rinfo_.pc_ += *--pos_;
404 }
405 
406 
407 void RelocIterator::AdvanceReadId() {
408  int x = 0;
409  for (int i = 0; i < kIntSize; i++) {
410  x |= static_cast<int>(*--pos_) << i * kBitsPerByte;
411  }
412  last_id_ += x;
413  rinfo_.data_ = last_id_;
414 }
415 
416 
417 void RelocIterator::AdvanceReadConstPoolData() {
418  int x = 0;
419  for (int i = 0; i < kIntSize; i++) {
420  x |= static_cast<int>(*--pos_) << i * kBitsPerByte;
421  }
422  rinfo_.data_ = x;
423 }
424 
425 
426 void RelocIterator::AdvanceReadPosition() {
427  int x = 0;
428  for (int i = 0; i < kIntSize; i++) {
429  x |= static_cast<int>(*--pos_) << i * kBitsPerByte;
430  }
431  last_position_ += x;
432  rinfo_.data_ = last_position_;
433 }
434 
435 
436 void RelocIterator::AdvanceReadData() {
437  intptr_t x = 0;
438  for (int i = 0; i < kIntptrSize; i++) {
439  x |= static_cast<intptr_t>(*--pos_) << i * kBitsPerByte;
440  }
441  rinfo_.data_ = x;
442 }
443 
444 
445 void RelocIterator::AdvanceReadVariableLengthPCJump() {
446  // Read the 32-kSmallPCDeltaBits most significant bits of the
447  // pc jump in kChunkBits bit chunks and shift them into place.
448  // Stop when the last chunk is encountered.
449  uint32_t pc_jump = 0;
450  for (int i = 0; i < kIntSize; i++) {
451  byte pc_jump_part = *--pos_;
452  pc_jump |= (pc_jump_part >> kLastChunkTagBits) << i * kChunkBits;
453  if ((pc_jump_part & kLastChunkTagMask) == 1) break;
454  }
455  // The least significant kSmallPCDeltaBits bits will be added
456  // later.
457  rinfo_.pc_ += pc_jump << kSmallPCDeltaBits;
458 }
459 
460 
461 inline int RelocIterator::GetLocatableTypeTag() {
462  return *pos_ & ((1 << kLocatableTypeTagBits) - 1);
463 }
464 
465 
466 inline void RelocIterator::ReadTaggedId() {
467  int8_t signed_b = *pos_;
468  // Signed right shift is arithmetic shift. Tested in test-utils.cc.
469  last_id_ += signed_b >> kLocatableTypeTagBits;
470  rinfo_.data_ = last_id_;
471 }
472 
473 
474 inline void RelocIterator::ReadTaggedPosition() {
475  int8_t signed_b = *pos_;
476  // Signed right shift is arithmetic shift. Tested in test-utils.cc.
477  last_position_ += signed_b >> kLocatableTypeTagBits;
478  rinfo_.data_ = last_position_;
479 }
480 
481 
482 static inline RelocInfo::Mode GetPositionModeFromTag(int tag) {
484  tag == kStatementPositionTag);
485  return (tag == kNonstatementPositionTag) ?
486  RelocInfo::POSITION :
487  RelocInfo::STATEMENT_POSITION;
488 }
489 
490 
492  ASSERT(!done());
493  // Basically, do the opposite of RelocInfoWriter::Write.
494  // Reading of data is as far as possible avoided for unwanted modes,
495  // but we must always update the pc.
496  //
497  // We exit this loop by returning when we find a mode we want.
498  while (pos_ > end_) {
499  int tag = AdvanceGetTag();
500  if (tag == kEmbeddedObjectTag) {
501  ReadTaggedPC();
502  if (SetMode(RelocInfo::EMBEDDED_OBJECT)) return;
503  } else if (tag == kCodeTargetTag) {
504  ReadTaggedPC();
505  if (SetMode(RelocInfo::CODE_TARGET)) return;
506  } else if (tag == kLocatableTag) {
507  ReadTaggedPC();
508  Advance();
509  int locatable_tag = GetLocatableTypeTag();
510  if (locatable_tag == kCodeWithIdTag) {
511  if (SetMode(RelocInfo::CODE_TARGET_WITH_ID)) {
512  ReadTaggedId();
513  return;
514  }
515  } else {
516  // Compact encoding is never used for comments,
517  // so it must be a position.
518  ASSERT(locatable_tag == kNonstatementPositionTag ||
519  locatable_tag == kStatementPositionTag);
520  if (mode_mask_ & RelocInfo::kPositionMask) {
521  ReadTaggedPosition();
522  if (SetMode(GetPositionModeFromTag(locatable_tag))) return;
523  }
524  }
525  } else {
526  ASSERT(tag == kDefaultTag);
527  int extra_tag = GetExtraTag();
528  if (extra_tag == kPCJumpExtraTag) {
529  if (GetTopTag() == kVariableLengthPCJumpTopTag) {
530  AdvanceReadVariableLengthPCJump();
531  } else {
532  AdvanceReadPC();
533  }
534  } else if (extra_tag == kDataJumpExtraTag) {
535  int locatable_tag = GetTopTag();
536  if (locatable_tag == kCodeWithIdTag) {
537  if (SetMode(RelocInfo::CODE_TARGET_WITH_ID)) {
538  AdvanceReadId();
539  return;
540  }
541  Advance(kIntSize);
542  } else if (locatable_tag != kCommentTag) {
543  ASSERT(locatable_tag == kNonstatementPositionTag ||
544  locatable_tag == kStatementPositionTag);
545  if (mode_mask_ & RelocInfo::kPositionMask) {
546  AdvanceReadPosition();
547  if (SetMode(GetPositionModeFromTag(locatable_tag))) return;
548  } else {
549  Advance(kIntSize);
550  }
551  } else {
552  ASSERT(locatable_tag == kCommentTag);
553  if (SetMode(RelocInfo::COMMENT)) {
554  AdvanceReadData();
555  return;
556  }
557  Advance(kIntptrSize);
558  }
559  } else if ((extra_tag == kConstPoolExtraTag) &&
560  (GetTopTag() == kConstPoolTag)) {
561  if (SetMode(RelocInfo::CONST_POOL)) {
562  AdvanceReadConstPoolData();
563  return;
564  }
565  Advance(kIntSize);
566  } else {
567  AdvanceReadPC();
568  int rmode = extra_tag + RelocInfo::LAST_COMPACT_ENUM;
569  if (SetMode(static_cast<RelocInfo::Mode>(rmode))) return;
570  }
571  }
572  }
573  done_ = true;
574 }
575 
576 
578  rinfo_.host_ = code;
579  rinfo_.pc_ = code->instruction_start();
580  rinfo_.data_ = 0;
581  // Relocation info is read backwards.
582  pos_ = code->relocation_start() + code->relocation_size();
583  end_ = code->relocation_start();
584  done_ = false;
585  mode_mask_ = mode_mask;
586  last_id_ = 0;
587  last_position_ = 0;
588  if (mode_mask_ == 0) pos_ = end_;
589  next();
590 }
591 
592 
593 RelocIterator::RelocIterator(const CodeDesc& desc, int mode_mask) {
594  rinfo_.pc_ = desc.buffer;
595  rinfo_.data_ = 0;
596  // Relocation info is read backwards.
597  pos_ = desc.buffer + desc.buffer_size;
598  end_ = pos_ - desc.reloc_size;
599  done_ = false;
600  mode_mask_ = mode_mask;
601  last_id_ = 0;
602  last_position_ = 0;
603  if (mode_mask_ == 0) pos_ = end_;
604  next();
605 }
606 
607 
608 // -----------------------------------------------------------------------------
609 // Implementation of RelocInfo
610 
611 
612 #ifdef ENABLE_DISASSEMBLER
613 const char* RelocInfo::RelocModeName(RelocInfo::Mode rmode) {
614  switch (rmode) {
615  case RelocInfo::NONE:
616  return "no reloc";
617  case RelocInfo::EMBEDDED_OBJECT:
618  return "embedded object";
619  case RelocInfo::CONSTRUCT_CALL:
620  return "code target (js construct call)";
621  case RelocInfo::CODE_TARGET_CONTEXT:
622  return "code target (context)";
624 #ifndef ENABLE_DEBUGGER_SUPPORT
625  UNREACHABLE();
626 #endif
627  return "debug break";
628  case RelocInfo::CODE_TARGET:
629  return "code target";
630  case RelocInfo::CODE_TARGET_WITH_ID:
631  return "code target with id";
632  case RelocInfo::GLOBAL_PROPERTY_CELL:
633  return "global property cell";
635  return "runtime entry";
636  case RelocInfo::JS_RETURN:
637  return "js return";
638  case RelocInfo::COMMENT:
639  return "comment";
640  case RelocInfo::POSITION:
641  return "position";
642  case RelocInfo::STATEMENT_POSITION:
643  return "statement position";
644  case RelocInfo::EXTERNAL_REFERENCE:
645  return "external reference";
646  case RelocInfo::INTERNAL_REFERENCE:
647  return "internal reference";
648  case RelocInfo::CONST_POOL:
649  return "constant pool";
650  case RelocInfo::DEBUG_BREAK_SLOT:
651 #ifndef ENABLE_DEBUGGER_SUPPORT
652  UNREACHABLE();
653 #endif
654  return "debug break slot";
655  case RelocInfo::NUMBER_OF_MODES:
656  UNREACHABLE();
657  return "number_of_modes";
658  }
659  return "unknown relocation type";
660 }
661 
662 
663 void RelocInfo::Print(FILE* out) {
664  PrintF(out, "%p %s", pc_, RelocModeName(rmode_));
665  if (IsComment(rmode_)) {
666  PrintF(out, " (%s)", reinterpret_cast<char*>(data_));
667  } else if (rmode_ == EMBEDDED_OBJECT) {
668  PrintF(out, " (");
669  target_object()->ShortPrint(out);
670  PrintF(out, ")");
671  } else if (rmode_ == EXTERNAL_REFERENCE) {
672  ExternalReferenceEncoder ref_encoder;
673  PrintF(out, " (%s) (%p)",
674  ref_encoder.NameOfAddress(*target_reference_address()),
675  *target_reference_address());
676  } else if (IsCodeTarget(rmode_)) {
677  Code* code = Code::GetCodeFromTargetAddress(target_address());
678  PrintF(out, " (%s) (%p)", Code::Kind2String(code->kind()),
679  target_address());
680  if (rmode_ == CODE_TARGET_WITH_ID) {
681  PrintF(" (id=%d)", static_cast<int>(data_));
682  }
683  } else if (IsPosition(rmode_)) {
684  PrintF(out, " (%" V8_PTR_PREFIX "d)", data());
685  } else if (rmode_ == RelocInfo::RUNTIME_ENTRY &&
686  Isolate::Current()->deoptimizer_data() != NULL) {
687  // Depotimization bailouts are stored as runtime entries.
689  target_address(), Deoptimizer::EAGER);
691  PrintF(out, " (deoptimization bailout %d)", id);
692  }
693  }
694 
695  PrintF(out, "\n");
696 }
697 #endif // ENABLE_DISASSEMBLER
698 
699 
700 #ifdef VERIFY_HEAP
701 void RelocInfo::Verify() {
702  switch (rmode_) {
703  case EMBEDDED_OBJECT:
704  Object::VerifyPointer(target_object());
705  break;
706  case GLOBAL_PROPERTY_CELL:
707  Object::VerifyPointer(target_cell());
708  break;
709  case DEBUG_BREAK:
710 #ifndef ENABLE_DEBUGGER_SUPPORT
711  UNREACHABLE();
712  break;
713 #endif
714  case CONSTRUCT_CALL:
715  case CODE_TARGET_CONTEXT:
716  case CODE_TARGET_WITH_ID:
717  case CODE_TARGET: {
718  // convert inline target address to code object
719  Address addr = target_address();
720  CHECK(addr != NULL);
721  // Check that we can find the right code object.
722  Code* code = Code::GetCodeFromTargetAddress(addr);
723  Object* found = HEAP->FindCodeObject(addr);
724  CHECK(found->IsCode());
725  CHECK(code->address() == HeapObject::cast(found)->address());
726  break;
727  }
728  case RUNTIME_ENTRY:
729  case JS_RETURN:
730  case COMMENT:
731  case POSITION:
732  case STATEMENT_POSITION:
733  case EXTERNAL_REFERENCE:
734  case INTERNAL_REFERENCE:
735  case CONST_POOL:
736  case DEBUG_BREAK_SLOT:
737  case NONE:
738  break;
739  case NUMBER_OF_MODES:
740  UNREACHABLE();
741  break;
742  }
743 }
744 #endif // VERIFY_HEAP
745 
746 
747 // -----------------------------------------------------------------------------
748 // Implementation of ExternalReference
749 
750 void ExternalReference::SetUp() {
751  double_constants.min_int = kMinInt;
752  double_constants.one_half = 0.5;
753  double_constants.minus_zero = -0.0;
754  double_constants.uint8_max_value = 255;
755  double_constants.zero = 0.0;
756  double_constants.canonical_non_hole_nan = OS::nan_value();
757  double_constants.the_hole_nan = BitCast<double>(kHoleNanInt64);
758  double_constants.negative_infinity = -V8_INFINITY;
759 }
760 
761 
762 ExternalReference::ExternalReference(Builtins::CFunctionId id, Isolate* isolate)
763  : address_(Redirect(isolate, Builtins::c_function_address(id))) {}
764 
765 
766 ExternalReference::ExternalReference(
767  ApiFunction* fun,
768  Type type = ExternalReference::BUILTIN_CALL,
769  Isolate* isolate = NULL)
770  : address_(Redirect(isolate, fun->address(), type)) {}
771 
772 
773 ExternalReference::ExternalReference(Builtins::Name name, Isolate* isolate)
774  : address_(isolate->builtins()->builtin_address(name)) {}
775 
776 
777 ExternalReference::ExternalReference(Runtime::FunctionId id,
778  Isolate* isolate)
779  : address_(Redirect(isolate, Runtime::FunctionForId(id)->entry)) {}
780 
781 
782 ExternalReference::ExternalReference(const Runtime::Function* f,
783  Isolate* isolate)
784  : address_(Redirect(isolate, f->entry)) {}
785 
786 
787 ExternalReference ExternalReference::isolate_address() {
788  return ExternalReference(Isolate::Current());
789 }
790 
791 
792 ExternalReference::ExternalReference(const IC_Utility& ic_utility,
793  Isolate* isolate)
794  : address_(Redirect(isolate, ic_utility.address())) {}
795 
796 #ifdef ENABLE_DEBUGGER_SUPPORT
797 ExternalReference::ExternalReference(const Debug_Address& debug_address,
798  Isolate* isolate)
799  : address_(debug_address.address(isolate)) {}
800 #endif
801 
802 ExternalReference::ExternalReference(StatsCounter* counter)
803  : address_(reinterpret_cast<Address>(counter->GetInternalPointer())) {}
804 
805 
806 ExternalReference::ExternalReference(Isolate::AddressId id, Isolate* isolate)
807  : address_(isolate->get_address_from_id(id)) {}
808 
809 
810 ExternalReference::ExternalReference(const SCTableReference& table_ref)
811  : address_(table_ref.address()) {}
812 
813 
814 ExternalReference ExternalReference::
815  incremental_marking_record_write_function(Isolate* isolate) {
816  return ExternalReference(Redirect(
817  isolate,
819 }
820 
821 
822 ExternalReference ExternalReference::
823  incremental_evacuation_record_write_function(Isolate* isolate) {
824  return ExternalReference(Redirect(
825  isolate,
827 }
828 
829 
830 ExternalReference ExternalReference::
831  store_buffer_overflow_function(Isolate* isolate) {
832  return ExternalReference(Redirect(
833  isolate,
835 }
836 
837 
838 ExternalReference ExternalReference::flush_icache_function(Isolate* isolate) {
839  return ExternalReference(Redirect(isolate, FUNCTION_ADDR(CPU::FlushICache)));
840 }
841 
842 
843 ExternalReference ExternalReference::perform_gc_function(Isolate* isolate) {
844  return
845  ExternalReference(Redirect(isolate, FUNCTION_ADDR(Runtime::PerformGC)));
846 }
847 
848 
849 ExternalReference ExternalReference::fill_heap_number_with_random_function(
850  Isolate* isolate) {
851  return ExternalReference(Redirect(
852  isolate,
854 }
855 
856 
857 ExternalReference ExternalReference::delete_handle_scope_extensions(
858  Isolate* isolate) {
859  return ExternalReference(Redirect(
860  isolate,
862 }
863 
864 
865 ExternalReference ExternalReference::random_uint32_function(
866  Isolate* isolate) {
867  return ExternalReference(Redirect(isolate, FUNCTION_ADDR(V8::Random)));
868 }
869 
870 
871 ExternalReference ExternalReference::get_date_field_function(
872  Isolate* isolate) {
873  return ExternalReference(Redirect(isolate, FUNCTION_ADDR(JSDate::GetField)));
874 }
875 
876 
877 ExternalReference ExternalReference::date_cache_stamp(Isolate* isolate) {
878  return ExternalReference(isolate->date_cache()->stamp_address());
879 }
880 
881 
882 ExternalReference ExternalReference::transcendental_cache_array_address(
883  Isolate* isolate) {
884  return ExternalReference(
885  isolate->transcendental_cache()->cache_array_address());
886 }
887 
888 
889 ExternalReference ExternalReference::new_deoptimizer_function(
890  Isolate* isolate) {
891  return ExternalReference(
892  Redirect(isolate, FUNCTION_ADDR(Deoptimizer::New)));
893 }
894 
895 
896 ExternalReference ExternalReference::compute_output_frames_function(
897  Isolate* isolate) {
898  return ExternalReference(
899  Redirect(isolate, FUNCTION_ADDR(Deoptimizer::ComputeOutputFrames)));
900 }
901 
902 
903 ExternalReference ExternalReference::keyed_lookup_cache_keys(Isolate* isolate) {
904  return ExternalReference(isolate->keyed_lookup_cache()->keys_address());
905 }
906 
907 
908 ExternalReference ExternalReference::keyed_lookup_cache_field_offsets(
909  Isolate* isolate) {
910  return ExternalReference(
911  isolate->keyed_lookup_cache()->field_offsets_address());
912 }
913 
914 
915 ExternalReference ExternalReference::roots_array_start(Isolate* isolate) {
916  return ExternalReference(isolate->heap()->roots_array_start());
917 }
918 
919 
920 ExternalReference ExternalReference::address_of_stack_limit(Isolate* isolate) {
921  return ExternalReference(isolate->stack_guard()->address_of_jslimit());
922 }
923 
924 
925 ExternalReference ExternalReference::address_of_real_stack_limit(
926  Isolate* isolate) {
927  return ExternalReference(isolate->stack_guard()->address_of_real_jslimit());
928 }
929 
930 
931 ExternalReference ExternalReference::address_of_regexp_stack_limit(
932  Isolate* isolate) {
933  return ExternalReference(isolate->regexp_stack()->limit_address());
934 }
935 
936 
937 ExternalReference ExternalReference::new_space_start(Isolate* isolate) {
938  return ExternalReference(isolate->heap()->NewSpaceStart());
939 }
940 
941 
942 ExternalReference ExternalReference::store_buffer_top(Isolate* isolate) {
943  return ExternalReference(isolate->heap()->store_buffer()->TopAddress());
944 }
945 
946 
947 ExternalReference ExternalReference::new_space_mask(Isolate* isolate) {
948  return ExternalReference(reinterpret_cast<Address>(
949  isolate->heap()->NewSpaceMask()));
950 }
951 
952 
953 ExternalReference ExternalReference::new_space_allocation_top_address(
954  Isolate* isolate) {
955  return ExternalReference(isolate->heap()->NewSpaceAllocationTopAddress());
956 }
957 
958 
959 ExternalReference ExternalReference::heap_always_allocate_scope_depth(
960  Isolate* isolate) {
961  Heap* heap = isolate->heap();
962  return ExternalReference(heap->always_allocate_scope_depth_address());
963 }
964 
965 
966 ExternalReference ExternalReference::new_space_allocation_limit_address(
967  Isolate* isolate) {
968  return ExternalReference(isolate->heap()->NewSpaceAllocationLimitAddress());
969 }
970 
971 
972 ExternalReference ExternalReference::handle_scope_level_address() {
973  return ExternalReference(HandleScope::current_level_address());
974 }
975 
976 
977 ExternalReference ExternalReference::handle_scope_next_address() {
978  return ExternalReference(HandleScope::current_next_address());
979 }
980 
981 
982 ExternalReference ExternalReference::handle_scope_limit_address() {
983  return ExternalReference(HandleScope::current_limit_address());
984 }
985 
986 
987 ExternalReference ExternalReference::scheduled_exception_address(
988  Isolate* isolate) {
989  return ExternalReference(isolate->scheduled_exception_address());
990 }
991 
992 
993 ExternalReference ExternalReference::address_of_pending_message_obj(
994  Isolate* isolate) {
995  return ExternalReference(isolate->pending_message_obj_address());
996 }
997 
998 
999 ExternalReference ExternalReference::address_of_has_pending_message(
1000  Isolate* isolate) {
1001  return ExternalReference(isolate->has_pending_message_address());
1002 }
1003 
1004 
1005 ExternalReference ExternalReference::address_of_pending_message_script(
1006  Isolate* isolate) {
1007  return ExternalReference(isolate->pending_message_script_address());
1008 }
1009 
1010 
1011 ExternalReference ExternalReference::address_of_min_int() {
1012  return ExternalReference(reinterpret_cast<void*>(&double_constants.min_int));
1013 }
1014 
1015 
1016 ExternalReference ExternalReference::address_of_one_half() {
1017  return ExternalReference(reinterpret_cast<void*>(&double_constants.one_half));
1018 }
1019 
1020 
1021 ExternalReference ExternalReference::address_of_minus_zero() {
1022  return ExternalReference(
1023  reinterpret_cast<void*>(&double_constants.minus_zero));
1024 }
1025 
1026 
1027 ExternalReference ExternalReference::address_of_zero() {
1028  return ExternalReference(reinterpret_cast<void*>(&double_constants.zero));
1029 }
1030 
1031 
1032 ExternalReference ExternalReference::address_of_uint8_max_value() {
1033  return ExternalReference(
1034  reinterpret_cast<void*>(&double_constants.uint8_max_value));
1035 }
1036 
1037 
1038 ExternalReference ExternalReference::address_of_negative_infinity() {
1039  return ExternalReference(
1040  reinterpret_cast<void*>(&double_constants.negative_infinity));
1041 }
1042 
1043 
1044 ExternalReference ExternalReference::address_of_canonical_non_hole_nan() {
1045  return ExternalReference(
1046  reinterpret_cast<void*>(&double_constants.canonical_non_hole_nan));
1047 }
1048 
1049 
1050 ExternalReference ExternalReference::address_of_the_hole_nan() {
1051  return ExternalReference(
1052  reinterpret_cast<void*>(&double_constants.the_hole_nan));
1053 }
1054 
1055 
1056 #ifndef V8_INTERPRETED_REGEXP
1057 
1058 ExternalReference ExternalReference::re_check_stack_guard_state(
1059  Isolate* isolate) {
1060  Address function;
1061 #ifdef V8_TARGET_ARCH_X64
1063 #elif V8_TARGET_ARCH_IA32
1065 #elif V8_TARGET_ARCH_ARM
1067 #elif V8_TARGET_ARCH_MIPS
1069 #else
1070  UNREACHABLE();
1071 #endif
1072  return ExternalReference(Redirect(isolate, function));
1073 }
1074 
1075 ExternalReference ExternalReference::re_grow_stack(Isolate* isolate) {
1076  return ExternalReference(
1078 }
1079 
1080 ExternalReference ExternalReference::re_case_insensitive_compare_uc16(
1081  Isolate* isolate) {
1082  return ExternalReference(Redirect(
1083  isolate,
1085 }
1086 
1087 ExternalReference ExternalReference::re_word_character_map() {
1088  return ExternalReference(
1090 }
1091 
1092 ExternalReference ExternalReference::address_of_static_offsets_vector(
1093  Isolate* isolate) {
1094  return ExternalReference(
1095  reinterpret_cast<Address>(isolate->jsregexp_static_offsets_vector()));
1096 }
1097 
1098 ExternalReference ExternalReference::address_of_regexp_stack_memory_address(
1099  Isolate* isolate) {
1100  return ExternalReference(
1101  isolate->regexp_stack()->memory_address());
1102 }
1103 
1104 ExternalReference ExternalReference::address_of_regexp_stack_memory_size(
1105  Isolate* isolate) {
1106  return ExternalReference(isolate->regexp_stack()->memory_size_address());
1107 }
1108 
1109 #endif // V8_INTERPRETED_REGEXP
1110 
1111 
1112 static double add_two_doubles(double x, double y) {
1113  return x + y;
1114 }
1115 
1116 
1117 static double sub_two_doubles(double x, double y) {
1118  return x - y;
1119 }
1120 
1121 
1122 static double mul_two_doubles(double x, double y) {
1123  return x * y;
1124 }
1125 
1126 
1127 static double div_two_doubles(double x, double y) {
1128  return x / y;
1129 }
1130 
1131 
1132 static double mod_two_doubles(double x, double y) {
1133  return modulo(x, y);
1134 }
1135 
1136 
1137 static double math_sin_double(double x) {
1138  return sin(x);
1139 }
1140 
1141 
1142 static double math_cos_double(double x) {
1143  return cos(x);
1144 }
1145 
1146 
1147 static double math_tan_double(double x) {
1148  return tan(x);
1149 }
1150 
1151 
1152 static double math_log_double(double x) {
1153  return log(x);
1154 }
1155 
1156 
1157 ExternalReference ExternalReference::math_sin_double_function(
1158  Isolate* isolate) {
1159  return ExternalReference(Redirect(isolate,
1160  FUNCTION_ADDR(math_sin_double),
1161  BUILTIN_FP_CALL));
1162 }
1163 
1164 
1165 ExternalReference ExternalReference::math_cos_double_function(
1166  Isolate* isolate) {
1167  return ExternalReference(Redirect(isolate,
1168  FUNCTION_ADDR(math_cos_double),
1169  BUILTIN_FP_CALL));
1170 }
1171 
1172 
1173 ExternalReference ExternalReference::math_tan_double_function(
1174  Isolate* isolate) {
1175  return ExternalReference(Redirect(isolate,
1176  FUNCTION_ADDR(math_tan_double),
1177  BUILTIN_FP_CALL));
1178 }
1179 
1180 
1181 ExternalReference ExternalReference::math_log_double_function(
1182  Isolate* isolate) {
1183  return ExternalReference(Redirect(isolate,
1184  FUNCTION_ADDR(math_log_double),
1185  BUILTIN_FP_CALL));
1186 }
1187 
1188 
1189 ExternalReference ExternalReference::page_flags(Page* page) {
1190  return ExternalReference(reinterpret_cast<Address>(page) +
1192 }
1193 
1194 
1195 // Helper function to compute x^y, where y is known to be an
1196 // integer. Uses binary decomposition to limit the number of
1197 // multiplications; see the discussion in "Hacker's Delight" by Henry
1198 // S. Warren, Jr., figure 11-6, page 213.
1199 double power_double_int(double x, int y) {
1200  double m = (y < 0) ? 1 / x : x;
1201  unsigned n = (y < 0) ? -y : y;
1202  double p = 1;
1203  while (n != 0) {
1204  if ((n & 1) != 0) p *= m;
1205  m *= m;
1206  if ((n & 2) != 0) p *= m;
1207  m *= m;
1208  n >>= 2;
1209  }
1210  return p;
1211 }
1212 
1213 
1214 double power_double_double(double x, double y) {
1215 #ifdef __MINGW64_VERSION_MAJOR
1216  // MinGW64 has a custom implementation for pow. This handles certain
1217  // special cases that are different.
1218  if ((x == 0.0 || isinf(x)) && isfinite(y)) {
1219  double f;
1220  if (modf(y, &f) != 0.0) return ((x == 0.0) ^ (y > 0)) ? V8_INFINITY : 0;
1221  }
1222 
1223  if (x == 2.0) {
1224  int y_int = static_cast<int>(y);
1225  if (y == y_int) return ldexp(1.0, y_int);
1226  }
1227 #endif
1228 
1229  // The checks for special cases can be dropped in ia32 because it has already
1230  // been done in generated code before bailing out here.
1231  if (isnan(y) || ((x == 1 || x == -1) && isinf(y))) return OS::nan_value();
1232  return pow(x, y);
1233 }
1234 
1235 
1236 ExternalReference ExternalReference::power_double_double_function(
1237  Isolate* isolate) {
1238  return ExternalReference(Redirect(isolate,
1240  BUILTIN_FP_FP_CALL));
1241 }
1242 
1243 
1244 ExternalReference ExternalReference::power_double_int_function(
1245  Isolate* isolate) {
1246  return ExternalReference(Redirect(isolate,
1248  BUILTIN_FP_INT_CALL));
1249 }
1250 
1251 
1252 static int native_compare_doubles(double y, double x) {
1253  if (x == y) return EQUAL;
1254  return x < y ? LESS : GREATER;
1255 }
1256 
1257 
1258 bool EvalComparison(Token::Value op, double op1, double op2) {
1260  switch (op) {
1261  case Token::EQ:
1262  case Token::EQ_STRICT: return (op1 == op2);
1263  case Token::NE: return (op1 != op2);
1264  case Token::LT: return (op1 < op2);
1265  case Token::GT: return (op1 > op2);
1266  case Token::LTE: return (op1 <= op2);
1267  case Token::GTE: return (op1 >= op2);
1268  default:
1269  UNREACHABLE();
1270  return false;
1271  }
1272 }
1273 
1274 
1275 ExternalReference ExternalReference::double_fp_operation(
1276  Token::Value operation, Isolate* isolate) {
1277  typedef double BinaryFPOperation(double x, double y);
1278  BinaryFPOperation* function = NULL;
1279  switch (operation) {
1280  case Token::ADD:
1281  function = &add_two_doubles;
1282  break;
1283  case Token::SUB:
1284  function = &sub_two_doubles;
1285  break;
1286  case Token::MUL:
1287  function = &mul_two_doubles;
1288  break;
1289  case Token::DIV:
1290  function = &div_two_doubles;
1291  break;
1292  case Token::MOD:
1293  function = &mod_two_doubles;
1294  break;
1295  default:
1296  UNREACHABLE();
1297  }
1298  return ExternalReference(Redirect(isolate,
1299  FUNCTION_ADDR(function),
1300  BUILTIN_FP_FP_CALL));
1301 }
1302 
1303 
1304 ExternalReference ExternalReference::compare_doubles(Isolate* isolate) {
1305  return ExternalReference(Redirect(isolate,
1306  FUNCTION_ADDR(native_compare_doubles),
1307  BUILTIN_COMPARE_CALL));
1308 }
1309 
1310 
1311 #ifdef ENABLE_DEBUGGER_SUPPORT
1312 ExternalReference ExternalReference::debug_break(Isolate* isolate) {
1313  return ExternalReference(Redirect(isolate, FUNCTION_ADDR(Debug_Break)));
1314 }
1315 
1316 
1317 ExternalReference ExternalReference::debug_step_in_fp_address(
1318  Isolate* isolate) {
1319  return ExternalReference(isolate->debug()->step_in_fp_addr());
1320 }
1321 #endif
1322 
1323 
1324 void PositionsRecorder::RecordPosition(int pos) {
1325  ASSERT(pos != RelocInfo::kNoPosition);
1326  ASSERT(pos >= 0);
1327  state_.current_position = pos;
1328 #ifdef ENABLE_GDB_JIT_INTERFACE
1329  if (gdbjit_lineinfo_ != NULL) {
1330  gdbjit_lineinfo_->SetPosition(assembler_->pc_offset(), pos, false);
1331  }
1332 #endif
1333 }
1334 
1335 
1336 void PositionsRecorder::RecordStatementPosition(int pos) {
1337  ASSERT(pos != RelocInfo::kNoPosition);
1338  ASSERT(pos >= 0);
1339  state_.current_statement_position = pos;
1340 #ifdef ENABLE_GDB_JIT_INTERFACE
1341  if (gdbjit_lineinfo_ != NULL) {
1342  gdbjit_lineinfo_->SetPosition(assembler_->pc_offset(), pos, true);
1343  }
1344 #endif
1345 }
1346 
1347 
1348 bool PositionsRecorder::WriteRecordedPositions() {
1349  bool written = false;
1350 
1351  // Write the statement position if it is different from what was written last
1352  // time.
1353  if (state_.current_statement_position != state_.written_statement_position) {
1354  EnsureSpace ensure_space(assembler_);
1355  assembler_->RecordRelocInfo(RelocInfo::STATEMENT_POSITION,
1356  state_.current_statement_position);
1357  state_.written_statement_position = state_.current_statement_position;
1358  written = true;
1359  }
1360 
1361  // Write the position if it is different from what was written last time and
1362  // also different from the written statement position.
1363  if (state_.current_position != state_.written_position &&
1364  state_.current_position != state_.written_statement_position) {
1365  EnsureSpace ensure_space(assembler_);
1366  assembler_->RecordRelocInfo(RelocInfo::POSITION, state_.current_position);
1367  state_.written_position = state_.current_position;
1368  written = true;
1369  }
1370 
1371  // Return whether something was written.
1372  return written;
1373 }
1374 
1375 } } // namespace v8::internal
byte * Address
Definition: globals.h:157
const int kConstPoolExtraTag
Definition: assembler.cc:233
RelocIterator(Code *code, int mode_mask=-1)
Definition: assembler.cc:577
const int kMinInt
Definition: globals.h:211
const int kPCJumpExtraTag
Definition: assembler.cc:212
static Address current_level_address()
Definition: handles.cc:115
const int kLastChunkTagBits
Definition: assembler.cc:221
bool is_intn(int x, int n)
Definition: assembler.h:832
void PrintF(const char *format,...)
Definition: v8utils.cc:40
const int kNonstatementPositionTag
Definition: assembler.cc:229
static void PerformGC(Object *result)
Definition: runtime.cc:13279
static void ComputeOutputFrames(Deoptimizer *deoptimizer)
Definition: deoptimizer.cc:349
static HeapObject * cast(Object *obj)
static bool IsCompareOp(Value op)
Definition: token.h:214
static Object * FillHeapNumberWithRandom(Object *heap_number, Context *context)
Definition: v8.cc:239
static void RecordWriteForEvacuationFromCode(HeapObject *obj, Object **slot, Isolate *isolate)
static Address current_next_address()
Definition: handles.cc:121
#define ASSERT(condition)
Definition: checks.h:270
v8::Handle< v8::Value > Print(const v8::Arguments &args)
static void StoreBufferOverflow(Isolate *isolate)
static const int kFlagsOffset
Definition: spaces.h:579
const int kTagBits
Definition: assembler.cc:201
static void RecordWriteFromCode(HeapObject *obj, Object *value, Isolate *isolate)
const int kLocatableTypeTagBits
Definition: assembler.cc:204
#define CHECK(condition)
Definition: checks.h:56
const int kCommentTag
Definition: assembler.cc:231
int isnan(double x)
const int kIntSize
Definition: globals.h:217
static Address current_limit_address()
Definition: handles.cc:127
#define V8_INFINITY
Definition: globals.h:32
const int kTagMask
Definition: assembler.cc:202
uint8_t byte
Definition: globals.h:156
const int kStatementPositionTag
Definition: assembler.cc:230
const uint64_t kHoleNanInt64
Definition: v8globals.h:473
static int CheckStackGuardState(Address *return_address, Code *re_code, Address re_frame)
#define UNREACHABLE()
Definition: checks.h:50
const int kSmallPCDeltaBits
Definition: assembler.cc:214
const int kExtraTagBits
Definition: assembler.cc:203
const int kConstPoolTag
Definition: assembler.cc:234
byte * instruction_start()
Definition: objects-inl.h:4649
const int kSmallDataBits
Definition: assembler.cc:205
const int kChunkMask
Definition: assembler.cc:220
static int CaseInsensitiveCompareUC16(Address byte_offset1, Address byte_offset2, size_t byte_length, Isolate *isolate)
double power_double_double(double x, double y)
Definition: assembler.cc:1214
const int kChunkBits
Definition: assembler.cc:219
double modulo(double x, double y)
int isinf(double x)
static Code * GetCodeFromTargetAddress(Address address)
Definition: objects-inl.h:3559
double power_double_int(double x, int y)
Definition: assembler.cc:1199
#define V8_PTR_PREFIX
Definition: globals.h:181
const int kBitsPerByte
Definition: globals.h:237
byte * relocation_start()
Definition: objects-inl.h:4675
#define BASE_EMBEDDED
Definition: allocation.h:68
static Object * GetField(Object *date, Smi *index)
Definition: objects.cc:13353
const int kMaxStandardNonCompactModes
Definition: assembler.cc:199
static int CheckStackGuardState(Address *return_address, Code *re_code, Address re_frame)
AssemblerBase(Isolate *isolate)
Definition: assembler.cc:109
const int kDataJumpExtraTag
Definition: assembler.cc:226
static int CheckStackGuardState(Address *return_address, Code *re_code, Address re_frame)
static double nan_value()
const int kSmallPCDeltaMask
Definition: assembler.cc:215
static uint32_t RandomPrivate(Isolate *isolate)
Definition: v8.cc:181
const int kCodeWithIdTag
Definition: assembler.cc:228
static const int kNotDeoptimizationEntry
Definition: deoptimizer.h:248
#define HEAP
Definition: isolate.h:1433
const int kLastChunkTag
Definition: assembler.cc:223
static Address GrowStack(Address stack_pointer, Address *stack_top, Isolate *isolate)
const int kLastChunkTagMask
Definition: assembler.cc:222
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
Definition: flags.cc:301
#define RUNTIME_ENTRY(name, nargs, ressize)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra code(assertions) for debugging") DEFINE_bool(code_comments
static void FlushICache(void *start, size_t size)
const int kDefaultTag
Definition: assembler.cc:210
#define FUNCTION_ADDR(f)
Definition: globals.h:293
const int kLocatableTag
Definition: assembler.cc:209
static int GetDeoptimizationId(Address addr, BailoutType type)
Definition: deoptimizer.cc:478
static int CheckStackGuardState(Address *return_address, Code *re_code, Address re_frame)
bool EvalComparison(Token::Value op, double op1, double op2)
Definition: assembler.cc:1258
int isfinite(double x)
const int kIntptrSize
Definition: globals.h:219
const int kCodeTargetTag
Definition: assembler.cc:208
bool is_uintn(int x, int n)
Definition: assembler.h:841
static void DeleteExtensions(Isolate *isolate)
Definition: handles.cc:99
static Deoptimizer * New(JSFunction *function, BailoutType type, unsigned bailout_id, Address from, int fp_to_sp_delta, Isolate *isolate)
Definition: deoptimizer.cc:79
const int kEmbeddedObjectTag
Definition: assembler.cc:207
const int kVariableLengthPCJumpTopTag
Definition: assembler.cc:218
static uint32_t Random(Context *context)
Definition: v8.cc:171