diff options
author | Konstantin Tokarev <annulen@yandex.ru> | 2016-08-25 19:20:41 +0300 |
---|---|---|
committer | Konstantin Tokarev <annulen@yandex.ru> | 2017-02-02 12:30:55 +0000 |
commit | 6882a04fb36642862b11efe514251d32070c3d65 (patch) | |
tree | b7959826000b061fd5ccc7512035c7478742f7b0 /Source/JavaScriptCore/bytecode/CodeOrigin.h | |
parent | ab6df191029eeeb0b0f16f127d553265659f739e (diff) | |
download | qtwebkit-6882a04fb36642862b11efe514251d32070c3d65.tar.gz |
Imported QtWebKit TP3 (git b57bc6801f1876c3220d5a4bfea33d620d477443)
Change-Id: I3b1d8a2808782c9f34d50240000e20cb38d3680f
Reviewed-by: Konstantin Tokarev <annulen@yandex.ru>
Diffstat (limited to 'Source/JavaScriptCore/bytecode/CodeOrigin.h')
-rw-r--r-- | Source/JavaScriptCore/bytecode/CodeOrigin.h | 135 |
1 files changed, 68 insertions, 67 deletions
diff --git a/Source/JavaScriptCore/bytecode/CodeOrigin.h b/Source/JavaScriptCore/bytecode/CodeOrigin.h index 5d9eaa041..66ab42724 100644 --- a/Source/JavaScriptCore/bytecode/CodeOrigin.h +++ b/Source/JavaScriptCore/bytecode/CodeOrigin.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved. + * Copyright (C) 2011-2015 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,11 +26,12 @@ #ifndef CodeOrigin_h #define CodeOrigin_h +#include "CallMode.h" #include "CodeBlockHash.h" #include "CodeSpecializationKind.h" -#include "ValueRecovery.h" #include "WriteBarrier.h" #include <wtf/BitVector.h> +#include <wtf/HashMap.h> #include <wtf/PrintStream.h> #include <wtf/StdLibExtras.h> #include <wtf/Vector.h> @@ -39,41 +40,45 @@ namespace JSC { struct InlineCallFrame; class ExecState; -class ExecutableBase; +class ScriptExecutable; class JSFunction; struct CodeOrigin { - static const unsigned maximumBytecodeIndex = (1u << 29) - 1; + static const unsigned invalidBytecodeIndex = UINT_MAX; - // Bytecode offset that you'd use to re-execute this instruction. - unsigned bytecodeIndex : 29; - // Bytecode offset corresponding to the opcode that gives the result (needed to handle - // op_call/op_call_put_result and op_method_check/op_get_by_id). - unsigned valueProfileOffset : 3; + // Bytecode offset that you'd use to re-execute this instruction, and the + // bytecode index of the bytecode instruction that produces some result that + // you're interested in (used for mapping Nodes whose values you're using + // to bytecode instructions that have the appropriate value profile). + unsigned bytecodeIndex; InlineCallFrame* inlineCallFrame; CodeOrigin() - : bytecodeIndex(maximumBytecodeIndex) - , valueProfileOffset(0) + : bytecodeIndex(invalidBytecodeIndex) , inlineCallFrame(0) { } - explicit CodeOrigin(unsigned bytecodeIndex, InlineCallFrame* inlineCallFrame = 0, unsigned valueProfileOffset = 0) + CodeOrigin(WTF::HashTableDeletedValueType) + : bytecodeIndex(invalidBytecodeIndex) + , inlineCallFrame(deletedMarker()) + { + } + + explicit CodeOrigin(unsigned bytecodeIndex, InlineCallFrame* inlineCallFrame = 0) : bytecodeIndex(bytecodeIndex) - , valueProfileOffset(valueProfileOffset) , inlineCallFrame(inlineCallFrame) { - RELEASE_ASSERT(bytecodeIndex <= maximumBytecodeIndex); - RELEASE_ASSERT(valueProfileOffset < (1u << 3)); + ASSERT(bytecodeIndex < invalidBytecodeIndex); } - bool isSet() const { return bytecodeIndex != maximumBytecodeIndex; } + bool isSet() const { return bytecodeIndex != invalidBytecodeIndex; } + explicit operator bool() const { return isSet(); } - unsigned bytecodeIndexForValueProfile() const + bool isHashTableDeletedValue() const { - return bytecodeIndex + valueProfileOffset; + return bytecodeIndex == invalidBytecodeIndex && !!inlineCallFrame; } // The inline depth is the depth of the inline stack, so 1 = not inlined, @@ -82,60 +87,42 @@ struct CodeOrigin { // If the code origin corresponds to inlined code, gives you the heap object that // would have owned the code if it had not been inlined. Otherwise returns 0. - ExecutableBase* codeOriginOwner() const; + CodeBlock* codeOriginOwner() const; - unsigned stackOffset() const; + int stackOffset() const; static unsigned inlineDepthForCallFrame(InlineCallFrame*); + unsigned hash() const; bool operator==(const CodeOrigin& other) const; - bool operator!=(const CodeOrigin& other) const { return !(*this == other); } - // Get the inline stack. This is slow, and is intended for debugging only. - Vector<CodeOrigin> inlineStack() const; + // This checks if the two code origins correspond to the same stack trace snippets, + // but ignore whether the InlineCallFrame's are identical. + bool isApproximatelyEqualTo(const CodeOrigin& other) const; - void dump(PrintStream&) const; -}; + unsigned approximateHash() const; -struct InlineCallFrame { - Vector<ValueRecovery> arguments; - WriteBarrier<ExecutableBase> executable; - WriteBarrier<JSFunction> callee; // This may be null, indicating that this is a closure call and that the JSFunction and JSScope are already on the stack. - CodeOrigin caller; - BitVector capturedVars; // Indexed by the machine call frame's variable numbering. - unsigned stackOffset : 31; - bool isCall : 1; - - CodeSpecializationKind specializationKind() const { return specializationFromIsCall(isCall); } + template <typename Function> + void walkUpInlineStack(const Function&); - bool isClosureCall() const { return !callee; } - - // Get the callee given a machine call frame to which this InlineCallFrame belongs. - JSFunction* calleeForCallFrame(ExecState*) const; - - String inferredName() const; - CodeBlockHash hash() const; - - CodeBlock* baselineCodeBlock() const; + // Get the inline stack. This is slow, and is intended for debugging only. + Vector<CodeOrigin> inlineStack() const; - void dumpBriefFunctionInformation(PrintStream&) const; void dump(PrintStream&) const; + void dumpInContext(PrintStream&, DumpContext*) const; - MAKE_PRINT_METHOD(InlineCallFrame, dumpBriefFunctionInformation, briefFunctionInformation); -}; - -struct CodeOriginAtCallReturnOffset { - CodeOrigin codeOrigin; - unsigned callReturnOffset; +private: + static InlineCallFrame* deletedMarker() + { + return bitwise_cast<InlineCallFrame*>(static_cast<uintptr_t>(1)); + } }; -inline unsigned CodeOrigin::stackOffset() const +inline unsigned CodeOrigin::hash() const { - if (!inlineCallFrame) - return 0; - - return inlineCallFrame->stackOffset; + return WTF::IntHash<unsigned>::hash(bytecodeIndex) + + WTF::PtrHash<InlineCallFrame*>::hash(inlineCallFrame); } inline bool CodeOrigin::operator==(const CodeOrigin& other) const @@ -143,20 +130,34 @@ inline bool CodeOrigin::operator==(const CodeOrigin& other) const return bytecodeIndex == other.bytecodeIndex && inlineCallFrame == other.inlineCallFrame; } - -inline unsigned getCallReturnOffsetForCodeOrigin(CodeOriginAtCallReturnOffset* data) -{ - return data->callReturnOffset; -} -inline ExecutableBase* CodeOrigin::codeOriginOwner() const -{ - if (!inlineCallFrame) - return 0; - return inlineCallFrame->executable.get(); -} +struct CodeOriginHash { + static unsigned hash(const CodeOrigin& key) { return key.hash(); } + static bool equal(const CodeOrigin& a, const CodeOrigin& b) { return a == b; } + static const bool safeToCompareToEmptyOrDeleted = true; +}; + +struct CodeOriginApproximateHash { + static unsigned hash(const CodeOrigin& key) { return key.approximateHash(); } + static bool equal(const CodeOrigin& a, const CodeOrigin& b) { return a.isApproximatelyEqualTo(b); } + static const bool safeToCompareToEmptyOrDeleted = true; +}; } // namespace JSC +namespace WTF { + +template<typename T> struct DefaultHash; +template<> struct DefaultHash<JSC::CodeOrigin> { + typedef JSC::CodeOriginHash Hash; +}; + +template<typename T> struct HashTraits; +template<> struct HashTraits<JSC::CodeOrigin> : SimpleClassHashTraits<JSC::CodeOrigin> { + static const bool emptyValueIsZero = false; +}; + +} // namespace WTF + #endif // CodeOrigin_h |