31
31
// The original source code covered by the above license above has been
32
32
// modified significantly by Google Inc.
33
// Copyright 2011 the V8 project authors. All rights reserved.
37
#include "arguments.h"
33
// Copyright 2012 the V8 project authors. All rights reserved.
35
#include "assembler.h"
37
#include <math.h> // For cos, log, pow, sin, tan, etc.
38
43
#include "deoptimizer.h"
39
44
#include "execution.h"
48
#include "lazy-instance.h"
50
#include "regexp-macro-assembler.h"
51
#include "regexp-stack.h"
42
52
#include "runtime.h"
43
#include "runtime-profiler.h"
44
53
#include "serialize.h"
54
#include "store-buffer-inl.h"
45
55
#include "stub-cache.h"
46
#include "regexp-stack.h"
48
#include "regexp-macro-assembler.h"
58
#if V8_TARGET_ARCH_IA32
59
#include "ia32/assembler-ia32-inl.h"
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
65
#include "mips/assembler-mips-inl.h"
67
#error "Unknown architecture."
50
70
// Include native regexp-macro-assembler.
51
71
#ifndef V8_INTERPRETED_REGEXP
52
72
#if V8_TARGET_ARCH_IA32
66
86
namespace internal {
69
const double DoubleConstant::min_int = kMinInt;
70
const double DoubleConstant::one_half = 0.5;
71
const double DoubleConstant::minus_zero = -0.0;
72
const double DoubleConstant::uint8_max_value = 255;
73
const double DoubleConstant::zero = 0.0;
74
const double DoubleConstant::canonical_non_hole_nan = OS::nan_value();
75
const double DoubleConstant::the_hole_nan = BitCast<double>(kHoleNanInt64);
76
const double DoubleConstant::negative_infinity = -V8_INFINITY;
88
// -----------------------------------------------------------------------------
89
// Common double constants.
91
struct DoubleConstant BASE_EMBEDDED {
96
double uint8_max_value;
97
double negative_infinity;
98
double canonical_non_hole_nan;
102
static DoubleConstant double_constants;
77
104
const char* const RelocInfo::kFillerCommentString = "DEOPTIMIZATION PADDING";
79
106
// -----------------------------------------------------------------------------
116
143
// The encoding relies on the fact that there are fewer than 14
117
// different non-compactly encoded relocation modes.
144
// different relocation modes using standard non-compact encoding.
119
146
// The first byte of a relocation record has a tag in its low 2 bits:
120
147
// Here are the record schemes, depending on the low tag and optional higher
146
173
// 00 [4 bit middle_tag] 11 followed by
147
174
// 00 [6 bit pc delta]
149
// 1101: not used (would allow one more relocation mode to be added)
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).
150
179
// 1110: long_data_record
151
180
// The format is: [2-bit data_type_tag] 1110 11
152
181
// signed intptr_t, lowest byte written first
201
230
const int kStatementPositionTag = 2;
202
231
const int kCommentTag = 3;
233
const int kConstPoolExtraTag = kPCJumpExtraTag - 2;
234
const int kConstPoolTag = 3;
205
237
uint32_t RelocInfoWriter::WriteVariableLengthPCJump(uint32_t pc_delta) {
206
238
// Return if the pc_delta can fit in kSmallPCDeltaBits bits.
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;
261
302
void RelocInfoWriter::WriteExtraTaggedData(intptr_t data_delta, int top_tag) {
262
303
WriteExtraTag(kDataJumpExtraTag, top_tag);
263
304
for (int i = 0; i < kIntptrSize; i++) {
273
314
byte* begin_pos = pos_;
275
316
ASSERT(rinfo->pc() - last_pc_ >= 0);
276
ASSERT(RelocInfo::NUMBER_OF_MODES - RelocInfo::LAST_COMPACT_ENUM <=
317
ASSERT(RelocInfo::LAST_STANDARD_NONCOMPACT_ENUM - RelocInfo::LAST_COMPACT_ENUM
318
<= kMaxStandardNonCompactModes);
278
319
// Use unsigned delta-encoding for pc.
279
320
uint32_t pc_delta = static_cast<uint32_t>(rinfo->pc() - last_pc_);
280
321
RelocInfo::Mode rmode = rinfo->rmode();
320
361
WriteExtraTaggedPC(pc_delta, kPCJumpExtraTag);
321
362
WriteExtraTaggedData(rinfo->data(), kCommentTag);
322
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()));
324
368
ASSERT(rmode > RelocInfo::LAST_COMPACT_ENUM);
325
369
int saved_mode = rmode - RelocInfo::LAST_COMPACT_ENUM;
473
526
ASSERT(tag == kDefaultTag);
474
527
int extra_tag = GetExtraTag();
475
528
if (extra_tag == kPCJumpExtraTag) {
476
int top_tag = GetTopTag();
477
if (top_tag == kVariableLengthPCJumpTopTag) {
529
if (GetTopTag() == kVariableLengthPCJumpTopTag) {
478
530
AdvanceReadVariableLengthPCJump();
655
717
case CODE_TARGET: {
656
718
// convert inline target address to code object
657
719
Address addr = target_address();
658
ASSERT(addr != NULL);
659
721
// Check that we can find the right code object.
660
722
Code* code = Code::GetCodeFromTargetAddress(addr);
661
723
Object* found = HEAP->FindCodeObject(addr);
662
ASSERT(found->IsCode());
663
ASSERT(code->address() == HeapObject::cast(found)->address());
724
CHECK(found->IsCode());
725
CHECK(code->address() == HeapObject::cast(found)->address());
666
728
case RUNTIME_ENTRY:
744
#endif // VERIFY_HEAP
684
747
// -----------------------------------------------------------------------------
685
748
// Implementation of ExternalReference
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;
687
762
ExternalReference::ExternalReference(Builtins::CFunctionId id, Isolate* isolate)
688
763
: address_(Redirect(isolate, Builtins::c_function_address(id))) {}
736
811
: address_(table_ref.address()) {}
814
ExternalReference ExternalReference::
815
incremental_marking_record_write_function(Isolate* isolate) {
816
return ExternalReference(Redirect(
818
FUNCTION_ADDR(IncrementalMarking::RecordWriteFromCode)));
822
ExternalReference ExternalReference::
823
incremental_evacuation_record_write_function(Isolate* isolate) {
824
return ExternalReference(Redirect(
826
FUNCTION_ADDR(IncrementalMarking::RecordWriteForEvacuationFromCode)));
830
ExternalReference ExternalReference::
831
store_buffer_overflow_function(Isolate* isolate) {
832
return ExternalReference(Redirect(
834
FUNCTION_ADDR(StoreBuffer::StoreBufferOverflow)));
838
ExternalReference ExternalReference::flush_icache_function(Isolate* isolate) {
839
return ExternalReference(Redirect(isolate, FUNCTION_ADDR(CPU::FlushICache)));
739
843
ExternalReference ExternalReference::perform_gc_function(Isolate* isolate) {
740
return ExternalReference(Redirect(isolate,
741
FUNCTION_ADDR(Runtime::PerformGC)));
845
ExternalReference(Redirect(isolate, FUNCTION_ADDR(Runtime::PerformGC)));
871
ExternalReference ExternalReference::get_date_field_function(
873
return ExternalReference(Redirect(isolate, FUNCTION_ADDR(JSDate::GetField)));
877
ExternalReference ExternalReference::date_cache_stamp(Isolate* isolate) {
878
return ExternalReference(isolate->date_cache()->stamp_address());
767
882
ExternalReference ExternalReference::transcendental_cache_array_address(
768
883
Isolate* isolate) {
769
884
return ExternalReference(
805
ExternalReference ExternalReference::the_hole_value_location(Isolate* isolate) {
806
return ExternalReference(isolate->factory()->the_hole_value().location());
810
ExternalReference ExternalReference::arguments_marker_location(
812
return ExternalReference(isolate->factory()->arguments_marker().location());
816
ExternalReference ExternalReference::roots_address(Isolate* isolate) {
817
return ExternalReference(isolate->heap()->roots_address());
915
ExternalReference ExternalReference::roots_array_start(Isolate* isolate) {
916
return ExternalReference(isolate->heap()->roots_array_start());
942
ExternalReference ExternalReference::store_buffer_top(Isolate* isolate) {
943
return ExternalReference(isolate->heap()->store_buffer()->TopAddress());
843
947
ExternalReference ExternalReference::new_space_mask(Isolate* isolate) {
844
Address mask = reinterpret_cast<Address>(isolate->heap()->NewSpaceMask());
845
return ExternalReference(mask);
948
return ExternalReference(reinterpret_cast<Address>(
949
isolate->heap()->NewSpaceMask()));
993
ExternalReference ExternalReference::address_of_pending_message_obj(
995
return ExternalReference(isolate->pending_message_obj_address());
999
ExternalReference ExternalReference::address_of_has_pending_message(
1001
return ExternalReference(isolate->has_pending_message_address());
1005
ExternalReference ExternalReference::address_of_pending_message_script(
1007
return ExternalReference(isolate->pending_message_script_address());
889
1011
ExternalReference ExternalReference::address_of_min_int() {
890
return ExternalReference(reinterpret_cast<void*>(
891
const_cast<double*>(&DoubleConstant::min_int)));
1012
return ExternalReference(reinterpret_cast<void*>(&double_constants.min_int));
895
1016
ExternalReference ExternalReference::address_of_one_half() {
896
return ExternalReference(reinterpret_cast<void*>(
897
const_cast<double*>(&DoubleConstant::one_half)));
1017
return ExternalReference(reinterpret_cast<void*>(&double_constants.one_half));
901
1021
ExternalReference ExternalReference::address_of_minus_zero() {
902
return ExternalReference(reinterpret_cast<void*>(
903
const_cast<double*>(&DoubleConstant::minus_zero)));
1022
return ExternalReference(
1023
reinterpret_cast<void*>(&double_constants.minus_zero));
907
1027
ExternalReference ExternalReference::address_of_zero() {
908
return ExternalReference(reinterpret_cast<void*>(
909
const_cast<double*>(&DoubleConstant::zero)));
1028
return ExternalReference(reinterpret_cast<void*>(&double_constants.zero));
913
1032
ExternalReference ExternalReference::address_of_uint8_max_value() {
914
return ExternalReference(reinterpret_cast<void*>(
915
const_cast<double*>(&DoubleConstant::uint8_max_value)));
1033
return ExternalReference(
1034
reinterpret_cast<void*>(&double_constants.uint8_max_value));
919
1038
ExternalReference ExternalReference::address_of_negative_infinity() {
920
return ExternalReference(reinterpret_cast<void*>(
921
const_cast<double*>(&DoubleConstant::negative_infinity)));
1039
return ExternalReference(
1040
reinterpret_cast<void*>(&double_constants.negative_infinity));
925
1044
ExternalReference ExternalReference::address_of_canonical_non_hole_nan() {
926
return ExternalReference(reinterpret_cast<void*>(
927
const_cast<double*>(&DoubleConstant::canonical_non_hole_nan)));
1045
return ExternalReference(
1046
reinterpret_cast<void*>(&double_constants.canonical_non_hole_nan));
931
1050
ExternalReference ExternalReference::address_of_the_hole_nan() {
932
return ExternalReference(reinterpret_cast<void*>(
933
const_cast<double*>(&DoubleConstant::the_hole_nan)));
1051
return ExternalReference(
1052
reinterpret_cast<void*>(&double_constants.the_hole_nan));
1173
ExternalReference ExternalReference::math_tan_double_function(
1175
return ExternalReference(Redirect(isolate,
1176
FUNCTION_ADDR(math_tan_double),
1049
1181
ExternalReference ExternalReference::math_log_double_function(
1050
1182
Isolate* isolate) {
1051
1183
return ExternalReference(Redirect(isolate,
1189
ExternalReference ExternalReference::page_flags(Page* page) {
1190
return ExternalReference(reinterpret_cast<Address>(page) +
1191
MemoryChunk::kFlagsOffset);
1057
1195
// Helper function to compute x^y, where y is known to be an
1058
1196
// integer. Uses binary decomposition to limit the number of
1059
1197
// multiplications; see the discussion in "Hacker's Delight" by Henry
1076
1214
double power_double_double(double x, double y) {
1077
int y_int = static_cast<int>(y);
1079
return power_double_int(x, y_int); // Returns 1.0 for exponent 0.
1082
if (y == 0.5) return sqrt(x + 0.0); // -0 must be converted to +0.
1083
if (y == -0.5) return 1.0 / sqrt(x + 0.0);
1085
if (isnan(y) || ((x == 1 || x == -1) && isinf(y))) {
1086
return OS::nan_value();
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)) {
1220
if (modf(y, &f) != 0.0) return ((x == 0.0) ^ (y > 0)) ? V8_INFINITY : 0;
1224
int y_int = static_cast<int>(y);
1225
if (y == y_int) return ldexp(1.0, y_int);
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();
1088
1232
return pow(x, y);
1258
bool EvalComparison(Token::Value op, double op1, double op2) {
1259
ASSERT(Token::IsCompareOp(op));
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);
1114
1275
ExternalReference ExternalReference::double_fp_operation(
1115
1276
Token::Value operation, Isolate* isolate) {
1116
1277
typedef double BinaryFPOperation(double x, double y);