diff options
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGUseKind.h')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGUseKind.h | 186 |
1 files changed, 171 insertions, 15 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGUseKind.h b/Source/JavaScriptCore/dfg/DFGUseKind.h index afe3d3540..41527f647 100644 --- a/Source/JavaScriptCore/dfg/DFGUseKind.h +++ b/Source/JavaScriptCore/dfg/DFGUseKind.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Apple Inc. All rights reserved. + * Copyright (C) 2013-2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,88 +26,244 @@ #ifndef DFGUseKind_h #define DFGUseKind_h -#include <wtf/Platform.h> - #if ENABLE(DFG_JIT) +#include "DFGNodeFlags.h" #include "SpeculatedType.h" #include <wtf/PrintStream.h> namespace JSC { namespace DFG { enum UseKind { - UntypedUse, + // The DFG has 3 representations of values used: + + // 1. The JSValue representation for a JSValue that must be stored in a GP + // register (or a GP register pair), and follows rules for boxing and unboxing + // that allow the JSValue to be stored as either fully boxed JSValues, or + // unboxed Int32, Booleans, Cells, etc. in 32-bit as appropriate. + UntypedUse, // UntypedUse must come first (value 0). Int32Use, KnownInt32Use, - RealNumberUse, + MachineIntUse, NumberUse, - KnownNumberUse, + RealNumberUse, BooleanUse, + KnownBooleanUse, CellUse, KnownCellUse, + CellOrOtherUse, ObjectUse, + FunctionUse, + FinalObjectUse, + RegExpObjectUse, ObjectOrOtherUse, + StringIdentUse, StringUse, + StringOrOtherUse, KnownStringUse, + KnownPrimitiveUse, // This bizarre type arises for op_strcat, which has a bytecode guarantee that it will only see primitives (i.e. not objects). + SymbolUse, StringObjectUse, StringOrStringObjectUse, + NotStringVarUse, NotCellUse, OtherUse, + MiscUse, + + // 2. The Double representation for an unboxed double value that must be stored + // in an FP register. + DoubleRepUse, + DoubleRepRealUse, + DoubleRepMachineIntUse, + + // 3. The Int52 representation for an unboxed integer value that must be stored + // in a GP register. + Int52RepUse, + LastUseKind // Must always be the last entry in the enum, as it is used to denote the number of enum elements. }; -ALWAYS_INLINE SpeculatedType typeFilterFor(UseKind useKind) +inline SpeculatedType typeFilterFor(UseKind useKind) { switch (useKind) { case UntypedUse: - return SpecEmptyOrTop; // TOP isn't good enough; untyped uses may use the normally unseen empty value, in the case of lazy registers. + return SpecFullTop; case Int32Use: case KnownInt32Use: return SpecInt32; - case RealNumberUse: - return SpecRealNumber; + case Int52RepUse: + return SpecMachineInt; + case MachineIntUse: + return SpecInt32 | SpecInt52AsDouble; case NumberUse: - case KnownNumberUse: - return SpecNumber; + return SpecBytecodeNumber; + case RealNumberUse: + return SpecBytecodeRealNumber; + case DoubleRepUse: + return SpecFullDouble; + case DoubleRepRealUse: + return SpecDoubleReal; + case DoubleRepMachineIntUse: + return SpecInt52AsDouble; case BooleanUse: + case KnownBooleanUse: return SpecBoolean; case CellUse: case KnownCellUse: return SpecCell; + case CellOrOtherUse: + return SpecCell | SpecOther; case ObjectUse: return SpecObject; + case FunctionUse: + return SpecFunction; + case FinalObjectUse: + return SpecFinalObject; + case RegExpObjectUse: + return SpecRegExpObject; case ObjectOrOtherUse: return SpecObject | SpecOther; + case StringIdentUse: + return SpecStringIdent; case StringUse: case KnownStringUse: return SpecString; + case StringOrOtherUse: + return SpecString | SpecOther; + case KnownPrimitiveUse: + return SpecHeapTop & ~SpecObject; + case SymbolUse: + return SpecSymbol; case StringObjectUse: return SpecStringObject; case StringOrStringObjectUse: return SpecString | SpecStringObject; + case NotStringVarUse: + return ~SpecStringVar; case NotCellUse: return ~SpecCell; case OtherUse: return SpecOther; + case MiscUse: + return SpecMisc; default: RELEASE_ASSERT_NOT_REACHED(); - return SpecTop; + return SpecFullTop; + } +} + +inline bool shouldNotHaveTypeCheck(UseKind kind) +{ + switch (kind) { + case UntypedUse: + case KnownInt32Use: + case KnownCellUse: + case KnownStringUse: + case KnownPrimitiveUse: + case KnownBooleanUse: + case Int52RepUse: + case DoubleRepUse: + return true; + default: + return false; } } -ALWAYS_INLINE bool isNumerical(UseKind kind) +inline bool mayHaveTypeCheck(UseKind kind) +{ + return !shouldNotHaveTypeCheck(kind); +} + +inline bool isNumerical(UseKind kind) { switch (kind) { case Int32Use: case KnownInt32Use: - case RealNumberUse: case NumberUse: + case RealNumberUse: + case Int52RepUse: + case DoubleRepUse: + case DoubleRepRealUse: + case MachineIntUse: + case DoubleRepMachineIntUse: + return true; + default: + return false; + } +} + +inline bool isDouble(UseKind kind) +{ + switch (kind) { + case DoubleRepUse: + case DoubleRepRealUse: + case DoubleRepMachineIntUse: return true; default: return false; } } +// Returns true if the use kind only admits cells, and is therefore appropriate for +// SpeculateCellOperand in the DFG or lowCell() in the FTL. +inline bool isCell(UseKind kind) +{ + switch (kind) { + case CellUse: + case KnownCellUse: + case ObjectUse: + case FunctionUse: + case FinalObjectUse: + case RegExpObjectUse: + case StringIdentUse: + case StringUse: + case KnownStringUse: + case SymbolUse: + case StringObjectUse: + case StringOrStringObjectUse: + return true; + default: + return false; + } +} + +// Returns true if it uses structure in a way that could be clobbered by +// things that change the structure. +inline bool usesStructure(UseKind kind) +{ + switch (kind) { + case StringObjectUse: + case StringOrStringObjectUse: + return true; + default: + return false; + } +} + +// Returns true if we've already guaranteed the type +inline bool alreadyChecked(UseKind kind, SpeculatedType type) +{ + // If the check involves the structure then we need to know more than just the type to be sure + // that the check is done. + if (usesStructure(kind)) + return false; + + return !(type & ~typeFilterFor(kind)); +} + +inline UseKind useKindForResult(NodeFlags result) +{ + ASSERT(!(result & ~NodeResultMask)); + switch (result) { + case NodeResultInt52: + return Int52RepUse; + case NodeResultDouble: + return DoubleRepUse; + default: + return UntypedUse; + } +} + } } // namespace JSC::DFG namespace WTF { |