summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/dfg/DFGUseKind.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGUseKind.h')
-rw-r--r--Source/JavaScriptCore/dfg/DFGUseKind.h186
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 {