diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/JavaScriptCore/ftl/FTLCapabilities.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/JavaScriptCore/ftl/FTLCapabilities.cpp')
-rw-r--r-- | Source/JavaScriptCore/ftl/FTLCapabilities.cpp | 348 |
1 files changed, 270 insertions, 78 deletions
diff --git a/Source/JavaScriptCore/ftl/FTLCapabilities.cpp b/Source/JavaScriptCore/ftl/FTLCapabilities.cpp index 86a28cf8a..81d566583 100644 --- a/Source/JavaScriptCore/ftl/FTLCapabilities.cpp +++ b/Source/JavaScriptCore/ftl/FTLCapabilities.cpp @@ -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 @@ -32,6 +32,11 @@ namespace JSC { namespace FTL { using namespace DFG; +static bool verboseCapabilities() +{ + return verboseCompilationEnabled() || Options::verboseFTLFailure(); +} + inline CapabilityLevel canCompile(Node* node) { // NOTE: If we ever have phantom arguments, we can compile them but we cannot @@ -39,11 +44,15 @@ inline CapabilityLevel canCompile(Node* node) switch (node->op()) { case JSConstant: - case WeakJSConstant: + case LazyJSConstant: case GetLocal: case SetLocal: + case PutStack: + case KillStack: + case GetStack: case MovHint: case ZombieHint: + case ExitOK: case Phantom: case Flush: case PhantomLocal: @@ -56,20 +65,28 @@ inline CapabilityLevel canCompile(Node* node) case BitLShift: case BitURShift: case CheckStructure: - case StructureTransitionWatchpoint: + case DoubleAsInt32: case ArrayifyToStructure: case PutStructure: - case PhantomPutStructure: case GetButterfly: case NewObject: case NewArray: + case NewArrayWithSpread: + case Spread: case NewArrayBuffer: + case NewTypedArray: case GetByOffset: + case GetGetterSetterByOffset: + case GetGetter: + case GetSetter: case PutByOffset: case GetGlobalVar: - case PutGlobalVar: + case GetGlobalLexicalVariable: + case PutGlobalVariable: case ValueAdd: + case StrCat: case ArithAdd: + case ArithClz32: case ArithSub: case ArithMul: case ArithDiv: @@ -77,61 +94,213 @@ inline CapabilityLevel canCompile(Node* node) case ArithMin: case ArithMax: case ArithAbs: + case ArithSin: + case ArithCos: + case ArithTan: + case ArithPow: + case ArithRandom: + case ArithRound: + case ArithFloor: + case ArithCeil: + case ArithTrunc: + case ArithSqrt: + case ArithLog: + case ArithFRound: case ArithNegate: case UInt32ToNumber: - case Int32ToDouble: - case CompareEqConstant: - case CompareStrictEqConstant: case Jump: case ForceOSRExit: case Phi: case Upsilon: case ExtractOSREntryLocal: case LoopHint: - case Call: - case Construct: - case GetMyScope: case SkipScope: - case GetClosureRegisters: + case GetGlobalObject: + case CreateActivation: + case NewFunction: + case NewGeneratorFunction: + case NewAsyncFunction: case GetClosureVar: case PutClosureVar: - case Int52ToValue: + case CreateDirectArguments: + case CreateScopedArguments: + case CreateClonedArguments: + case GetFromArguments: + case PutToArguments: + case GetArgument: case InvalidationPoint: case StringCharAt: - case CheckFunction: + case CheckCell: + case CheckBadCell: + case CheckNotEmpty: + case CheckStringIdent: + case CheckWatchdogTimer: case StringCharCodeAt: + case StringFromCharCode: case AllocatePropertyStorage: - case FunctionReentryWatchpoint: - case TypedArrayWatchpoint: - case VariableWatchpoint: + case ReallocatePropertyStorage: + case NukeStructureAndSetButterfly: + case GetTypedArrayByteOffset: case NotifyWrite: case StoreBarrier: - case ConditionalStoreBarrier: - case StoreBarrierWithNullCheck: + case FencedStoreBarrier: + case Call: + case DirectCall: + case TailCall: + case DirectTailCall: + case TailCallInlinedCaller: + case DirectTailCallInlinedCaller: + case Construct: + case DirectConstruct: + case CallVarargs: + case CallEval: + case TailCallVarargs: + case TailCallVarargsInlinedCaller: + case ConstructVarargs: + case CallForwardVarargs: + case TailCallForwardVarargs: + case TailCallForwardVarargsInlinedCaller: + case ConstructForwardVarargs: + case LoadVarargs: case ValueToInt32: case Branch: case LogicalNot: case CheckInBounds: case ConstantStoragePointer: case Check: - // These are OK. - break; + case CountExecution: + case GetExecutable: + case GetScope: + case GetCallee: + case GetArgumentCountIncludingThis: + case ToNumber: + case ToString: + case CallObjectConstructor: + case CallStringConstructor: + case MakeRope: + case NewArrayWithSize: + case TryGetById: case GetById: - case PutById: - if (node->child1().useKind() == CellUse) - break; - return CannotCompile; + case GetByIdFlush: + case GetByIdWithThis: + case ToThis: + case MultiGetByOffset: + case MultiPutByOffset: + case ToPrimitive: + case Throw: + case ThrowStaticError: + case Unreachable: + case In: + case HasOwnProperty: + case IsCellWithType: + case MapHash: + case GetMapBucket: + case LoadFromJSMapBucket: + case IsNonEmptyMapBucket: + case IsEmpty: + case IsUndefined: + case IsBoolean: + case IsNumber: + case IsObject: + case IsObjectOrNull: + case IsFunction: + case IsTypedArrayView: + case CheckTypeInfoFlags: + case OverridesHasInstance: + case InstanceOf: + case InstanceOfCustom: + case DoubleRep: + case ValueRep: + case Int52Rep: + case DoubleConstant: + case Int52Constant: + case BooleanToNumber: + case HasGenericProperty: + case HasStructureProperty: + case GetDirectPname: + case GetEnumerableLength: case GetIndexedPropertyStorage: - if (node->arrayMode().type() == Array::String) - break; - if (isTypedView(node->arrayMode().typedArrayType())) - break; - return CannotCompile; + case GetPropertyEnumerator: + case GetEnumeratorStructurePname: + case GetEnumeratorGenericPname: + case ToIndexString: + case BottomValue: + case PhantomNewObject: + case PhantomNewFunction: + case PhantomNewGeneratorFunction: + case PhantomNewAsyncFunction: + case PhantomCreateActivation: + case PutHint: + case CheckStructureImmediate: + case MaterializeNewObject: + case MaterializeCreateActivation: + case PhantomDirectArguments: + case PhantomCreateRest: + case PhantomSpread: + case PhantomNewArrayWithSpread: + case PhantomClonedArguments: + case GetMyArgumentByVal: + case GetMyArgumentByValOutOfBounds: + case ForwardVarargs: + case Switch: + case TypeOf: + case PutById: + case PutByIdDirect: + case PutByIdFlush: + case PutByIdWithThis: + case PutGetterById: + case PutSetterById: + case PutGetterSetterById: + case PutGetterByVal: + case PutSetterByVal: + case CreateRest: + case GetRestLength: + case RegExpExec: + case RegExpTest: + case NewRegexp: + case StringReplace: + case StringReplaceRegExp: + case GetRegExpObjectLastIndex: + case SetRegExpObjectLastIndex: + case RecordRegExpCachedResult: + case SetFunctionName: + case LogShadowChickenPrologue: + case LogShadowChickenTail: + case ResolveScope: + case GetDynamicVar: + case PutDynamicVar: + case CompareEq: + case CompareEqPtr: + case CompareLess: + case CompareLessEq: + case CompareGreater: + case CompareGreaterEq: + case CompareStrictEq: + case DefineDataProperty: + case DefineAccessorProperty: + case ToLowerCase: + case NumberToStringWithRadix: + case CheckDOM: + case CallDOM: + case CallDOMGetter: + case ArraySlice: + case ParseInt: + // These are OK. + break; + + case Identity: + // No backend handles this because it will be optimized out. But we may check + // for capabilities before optimization. It would be a deep error to remove this + // case because it would prevent us from catching bugs where the FTL backend + // pipeline failed to optimize out an Identity. + break; case CheckArray: switch (node->arrayMode().type()) { case Array::Int32: case Array::Double: case Array::Contiguous: + case Array::DirectArguments: + case Array::ScopedArguments: break; default: if (isTypedView(node->arrayMode().typedArrayType())) @@ -141,17 +310,31 @@ inline CapabilityLevel canCompile(Node* node) break; case GetArrayLength: switch (node->arrayMode().type()) { + case Array::Undecided: case Array::Int32: case Array::Double: case Array::Contiguous: case Array::String: + case Array::DirectArguments: + case Array::ScopedArguments: break; default: - if (isTypedView(node->arrayMode().typedArrayType())) + if (node->arrayMode().isSomeTypedArrayView()) break; return CannotCompile; } break; + case HasIndexedProperty: + switch (node->arrayMode().type()) { + case Array::ForceExit: + case Array::Int32: + case Array::Double: + case Array::Contiguous: + break; + default: + return CannotCompile; + } + break; case GetByVal: switch (node->arrayMode().type()) { case Array::ForceExit: @@ -160,6 +343,9 @@ inline CapabilityLevel canCompile(Node* node) case Array::Int32: case Array::Double: case Array::Contiguous: + case Array::Undecided: + case Array::DirectArguments: + case Array::ScopedArguments: break; default: if (isTypedView(node->arrayMode().typedArrayType())) @@ -167,6 +353,8 @@ inline CapabilityLevel canCompile(Node* node) return CannotCompile; } break; + case GetByValWithThis: + break; case PutByVal: case PutByValAlias: case PutByValDirect: @@ -183,45 +371,14 @@ inline CapabilityLevel canCompile(Node* node) return CannotCompile; } break; - case CompareEq: - if (node->isBinaryUseKind(Int32Use)) - break; - if (node->isBinaryUseKind(MachineIntUse)) - break; - if (node->isBinaryUseKind(NumberUse)) - break; - if (node->isBinaryUseKind(ObjectUse)) - break; - if (node->isBinaryUseKind(UntypedUse)) - break; - return CannotCompile; - case CompareStrictEq: - if (node->isBinaryUseKind(Int32Use)) - break; - if (node->isBinaryUseKind(MachineIntUse)) - break; - if (node->isBinaryUseKind(NumberUse)) - break; - if (node->isBinaryUseKind(ObjectUse)) - break; - return CannotCompile; - case CompareLess: - case CompareLessEq: - case CompareGreater: - case CompareGreaterEq: - if (node->isBinaryUseKind(Int32Use)) - break; - if (node->isBinaryUseKind(MachineIntUse)) - break; - if (node->isBinaryUseKind(NumberUse)) - break; - if (node->isBinaryUseKind(UntypedUse)) - break; - return CannotCompile; - case Switch: - switch (node->switchData()->kind) { - case SwitchImm: - case SwitchChar: + case PutByValWithThis: + break; + case ArrayPush: + case ArrayPop: + switch (node->arrayMode().type()) { + case Array::Int32: + case Array::Contiguous: + case Array::Double: break; default: return CannotCompile; @@ -236,9 +393,21 @@ inline CapabilityLevel canCompile(Node* node) CapabilityLevel canCompile(Graph& graph) { + if (graph.m_codeBlock->instructionCount() > Options::maximumFTLCandidateInstructionCount()) { + if (verboseCapabilities()) + dataLog("FTL rejecting ", *graph.m_codeBlock, " because it's too big.\n"); + return CannotCompile; + } + if (graph.m_codeBlock->codeType() != FunctionCode) { - if (verboseCompilationEnabled()) - dataLog("FTL rejecting code block that doesn't belong to a function.\n"); + if (verboseCapabilities()) + dataLog("FTL rejecting ", *graph.m_codeBlock, " because it doesn't belong to a function.\n"); + return CannotCompile; + } + + if (UNLIKELY(graph.m_codeBlock->ownerScriptExecutable()->neverFTLOptimize())) { + if (verboseCapabilities()) + dataLog("FTL rejecting ", *graph.m_codeBlock, " because it is marked as never FTL compile.\n"); return CannotCompile; } @@ -264,23 +433,46 @@ CapabilityLevel canCompile(Graph& graph) case UntypedUse: case Int32Use: case KnownInt32Use: - case MachineIntUse: + case Int52RepUse: case NumberUse: - case KnownNumberUse: case RealNumberUse: + case DoubleRepUse: + case DoubleRepRealUse: case BooleanUse: + case KnownBooleanUse: case CellUse: case KnownCellUse: + case CellOrOtherUse: case ObjectUse: + case ArrayUse: + case FunctionUse: case ObjectOrOtherUse: case StringUse: + case StringOrOtherUse: + case KnownStringUse: + case KnownPrimitiveUse: + case StringObjectUse: + case StringOrStringObjectUse: + case SymbolUse: + case MapObjectUse: + case SetObjectUse: case FinalObjectUse: + case RegExpObjectUse: + case ProxyObjectUse: + case DerivedArrayUse: + case NotCellUse: + case OtherUse: + case MiscUse: + case StringIdentUse: + case NotStringVarUse: + case AnyIntUse: + case DoubleRepAnyIntUse: // These are OK. break; default: // Don't know how to handle anything else. - if (verboseCompilationEnabled()) { - dataLog("FTL rejecting node because of bad use kind: ", edge.useKind(), " in node:\n"); + if (verboseCapabilities()) { + dataLog("FTL rejecting node in ", *graph.m_codeBlock, " because of bad use kind: ", edge.useKind(), " in node:\n"); graph.dump(WTF::dataFile(), " ", node); } return CannotCompile; @@ -289,8 +481,8 @@ CapabilityLevel canCompile(Graph& graph) switch (canCompile(node)) { case CannotCompile: - if (verboseCompilationEnabled()) { - dataLog("FTL rejecting node:\n"); + if (verboseCapabilities()) { + dataLog("FTL rejecting node in ", *graph.m_codeBlock, ":\n"); graph.dump(WTF::dataFile(), " ", node); } return CannotCompile; |