15 IC::Clear(isolate, address, constant_pool);
20 : argc_(ArgcBits::decode(extra_ic_state)),
21 call_type_(CallTypeBits::decode(extra_ic_state)) {}
26 ArgcBits::encode(argc_) | CallTypeBits::encode(call_type_);
27 return extra_ic_state;
32 return os <<
"(args(" << s.arg_count() <<
"), "
33 << (s.call_type() == CallICState::METHOD ?
"METHOD" :
"FUNCTION")
41 static_cast<Token::Value>(FIRST_TOKEN + OpField::decode(extra_ic_state));
42 mode_ = OverwriteModeField::decode(extra_ic_state);
44 Maybe<int>(HasFixedRightArgField::decode(extra_ic_state),
45 1 << FixedRightArgValueField::decode(extra_ic_state));
46 left_kind_ = LeftKindField::decode(extra_ic_state);
47 if (fixed_right_arg_.has_value) {
48 right_kind_ =
Smi::IsValid(fixed_right_arg_.value) ? SMI : INT32;
50 right_kind_ = RightKindField::decode(extra_ic_state);
52 result_kind_ = ResultKindField::decode(extra_ic_state);
60 OpField::encode(op_ - FIRST_TOKEN) | OverwriteModeField::encode(mode_) |
61 LeftKindField::encode(left_kind_) |
62 ResultKindField::encode(result_kind_) |
63 HasFixedRightArgField::encode(fixed_right_arg_.has_value);
64 if (fixed_right_arg_.has_value) {
65 extra_ic_state = FixedRightArgValueField::update(
68 extra_ic_state = RightKindField::update(extra_ic_state, right_kind_);
70 return extra_ic_state;
75 void BinaryOpICState::GenerateAheadOfTime(
76 Isolate* isolate,
void (*Generate)(Isolate*,
const BinaryOpICState&)) {
81 #define GENERATE(op, left_kind, right_kind, result_kind, mode) \
83 BinaryOpICState state(isolate, op, mode); \
84 state.left_kind_ = left_kind; \
85 state.fixed_right_arg_.has_value = false; \
86 state.right_kind_ = right_kind; \
87 state.result_kind_ = result_kind; \
88 Generate(isolate, state); \
276 #define GENERATE(op, left_kind, fixed_right_arg_value, result_kind, mode) \
278 BinaryOpICState state(isolate, op, mode); \
279 state.left_kind_ = left_kind; \
280 state.fixed_right_arg_.has_value = true; \
281 state.fixed_right_arg_.value = fixed_right_arg_value; \
282 state.right_kind_ = SMI; \
283 state.result_kind_ = result_kind; \
284 Generate(isolate, state); \
297 Type* BinaryOpICState::GetResultType(Zone* zone)
const {
298 Kind result_kind = result_kind_;
299 if (HasSideEffects()) {
302 return Type::Union(Type::Number(zone), Type::String(zone), zone);
303 }
else if (result_kind == NUMBER && op_ == Token::SHR) {
304 return Type::Unsigned32(zone);
307 return KindToType(result_kind, zone);
312 os <<
"(" << Token::Name(s.op_);
317 if (s.CouldCreateAllocationMementos()) os <<
"_CreateAllocationMementos";
318 os <<
":" << BinaryOpICState::KindToString(s.left_kind_) <<
"*";
319 if (s.fixed_right_arg_.has_value) {
320 os << s.fixed_right_arg_.value;
322 os << BinaryOpICState::KindToString(s.right_kind_);
324 return os <<
"->" << BinaryOpICState::KindToString(s.result_kind_) <<
")";
332 left_kind_ = UpdateKind(left, left_kind_);
333 right_kind_ = UpdateKind(right, right_kind_);
335 int32_t fixed_right_arg_value = 0;
336 bool has_fixed_right_arg =
337 op_ == Token::MOD && right->ToInt32(&fixed_right_arg_value) &&
338 fixed_right_arg_value > 0 &&
340 FixedRightArgValueField::is_valid(
WhichPowerOf2(fixed_right_arg_value)) &&
341 (left_kind_ == SMI || left_kind_ == INT32) &&
342 (result_kind_ ==
NONE || !fixed_right_arg_.has_value);
343 fixed_right_arg_ =
Maybe<int32_t>(has_fixed_right_arg, fixed_right_arg_value);
345 result_kind_ = UpdateKind(result, result_kind_);
347 if (!Token::IsTruncatingBinaryOp(op_)) {
348 Kind input_kind =
Max(left_kind_, right_kind_);
349 if (result_kind_ < input_kind && input_kind <= NUMBER) {
350 result_kind_ = input_kind;
356 if (left_kind_ ==
STRING && right_kind_ == INT32) {
359 right_kind_ = NUMBER;
360 }
else if (right_kind_ ==
STRING && left_kind_ == INT32) {
370 result_kind_ > NUMBER) {
374 if (old_extra_ic_state == GetExtraICState()) {
376 if (left->IsUndefined() || left->IsBoolean()) {
379 DCHECK(right->IsUndefined() || right->IsBoolean());
386 BinaryOpICState::Kind BinaryOpICState::UpdateKind(Handle<Object>
object,
389 bool is_truncating = Token::IsTruncatingBinaryOp(op());
390 if (object->IsBoolean() && is_truncating) {
393 }
else if (object->IsUndefined()) {
395 new_kind = is_truncating ? INT32 : NUMBER;
396 }
else if (object->IsSmi()) {
398 }
else if (object->IsHeapNumber()) {
399 double value = Handle<HeapNumber>::cast(
object)->value();
401 }
else if (object->IsString() && op() ==
Token::ADD) {
407 if (kind !=
NONE && ((new_kind <= NUMBER && kind > NUMBER) ||
408 (new_kind > NUMBER && kind <= NUMBER))) {
411 return Max(kind, new_kind);
416 const char* BinaryOpICState::KindToString(Kind kind) {
437 Type* BinaryOpICState::KindToType(Kind kind, Zone* zone) {
442 return Type::SignedSmall(zone);
444 return Type::Signed32(zone);
446 return Type::Number(zone);
448 return Type::String(zone);
450 return Type::Any(zone);
457 const char* CompareICState::GetStateName(
State state) {
460 return "UNINITIALIZED";
466 return "INTERNALIZED_STRING";
470 return "UNIQUE_NAME";
474 return "KNOWN_OBJECT";
488 return Type::SignedSmall(zone);
490 return Type::Number(zone);
492 return Type::String(zone);
494 return Type::InternalizedString(zone);
496 return Type::UniqueName(zone);
498 return Type::Receiver(zone);
500 return map.is_null() ? Type::Receiver(zone) : Type::Class(
map, zone);
502 return Type::Any(zone);
513 if (value->IsSmi())
return SMI;
514 if (value->IsHeapNumber())
return NUMBER;
516 if (value->IsString())
return STRING;
517 if (value->IsSymbol())
return UNIQUE_NAME;
518 if (value->IsJSObject())
return OBJECT;
521 if (value->IsSmi())
return SMI;
522 if (value->IsHeapNumber())
return NUMBER;
525 if (value->IsNumber())
return NUMBER;
529 if (value->IsString())
return STRING;
530 if (value->IsSymbol())
return UNIQUE_NAME;
533 if (value->IsString())
return STRING;
536 if (value->IsUniqueName())
return UNIQUE_NAME;
539 if (value->IsJSObject())
return OBJECT;
557 if (x->IsSmi() &&
y->IsSmi())
return SMI;
558 if (x->IsNumber() &&
y->IsNumber())
return NUMBER;
559 if (Token::IsOrderedRelationalCompareOp(op)) {
562 if ((x->IsNumber() &&
y->IsUndefined()) ||
563 (
y->IsNumber() && x->IsUndefined())) {
567 if (x->IsInternalizedString() &&
y->IsInternalizedString()) {
572 if (x->IsString() &&
y->IsString())
return STRING;
573 if (!Token::IsEqualityOp(op))
return GENERIC;
574 if (x->IsUniqueName() &&
y->IsUniqueName())
return UNIQUE_NAME;
575 if (x->IsJSObject() &&
y->IsJSObject()) {
585 return x->IsNumber() &&
y->IsNumber() ? NUMBER :
GENERIC;
587 DCHECK(Token::IsEqualityOp(op));
588 if (x->IsString() &&
y->IsString())
return STRING;
589 if (x->IsUniqueName() &&
y->IsUniqueName())
return UNIQUE_NAME;
595 if (old_left == SMI && x->IsHeapNumber())
return NUMBER;
596 if (old_right == SMI &&
y->IsHeapNumber())
return NUMBER;
599 DCHECK(Token::IsEqualityOp(op));
600 if (x->IsJSObject() &&
y->IsJSObject()) {
Isolate represents an isolated instance of the V8 engine.
static void Clear(Isolate *isolate, Address address, ConstantPoolArray *constant_pool)
static void Clear(Isolate *isolate, Address address, ConstantPoolArray *constant_pool)
static bool IsValid(intptr_t value)
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf map
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define INTERNALIZED_STRING(name, value)
#define GENERATE(op, left_kind, right_kind, result_kind, mode)
#define DCHECK_LE(v1, v2)
#define DCHECK_NE(v1, v2)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
bool IsPowerOfTwo32(uint32_t value)
static LifetimePosition Max(LifetimePosition a, LifetimePosition b)
int WhichPowerOf2(uint32_t x)
TypeImpl< ZoneTypeConfig > Type
static bool IsInt32Double(double value)
OStream & operator<<(OStream &os, const BinaryOpICState &s)
OStream & operator<<(OStream &os, const BasicBlockProfiler &p)
static bool SmiValuesAre32Bits()
Debugger support for the V8 JavaScript engine.