summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/bytecode/DFGExitProfile.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/bytecode/DFGExitProfile.h')
-rw-r--r--Source/JavaScriptCore/bytecode/DFGExitProfile.h65
1 files changed, 49 insertions, 16 deletions
diff --git a/Source/JavaScriptCore/bytecode/DFGExitProfile.h b/Source/JavaScriptCore/bytecode/DFGExitProfile.h
index ab1a60d58..337e3ec01 100644
--- a/Source/JavaScriptCore/bytecode/DFGExitProfile.h
+++ b/Source/JavaScriptCore/bytecode/DFGExitProfile.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2014, 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
@@ -23,13 +23,14 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef DFGExitProfile_h
-#define DFGExitProfile_h
+#pragma once
-#include "ConcurrentJITLock.h"
+#if ENABLE(DFG_JIT)
+
+#include "ConcurrentJSLock.h"
#include "ExitKind.h"
+#include "ExitingJITType.h"
#include <wtf/HashSet.h>
-#include <wtf/OwnPtr.h>
#include <wtf/Vector.h>
namespace JSC { namespace DFG {
@@ -39,18 +40,21 @@ public:
FrequentExitSite()
: m_bytecodeOffset(0) // 0 = empty value
, m_kind(ExitKindUnset)
+ , m_jitType(ExitFromAnything)
{
}
FrequentExitSite(WTF::HashTableDeletedValueType)
: m_bytecodeOffset(1) // 1 = deleted value
, m_kind(ExitKindUnset)
+ , m_jitType(ExitFromAnything)
{
}
- explicit FrequentExitSite(unsigned bytecodeOffset, ExitKind kind)
+ explicit FrequentExitSite(unsigned bytecodeOffset, ExitKind kind, ExitingJITType jitType = ExitFromAnything)
: m_bytecodeOffset(bytecodeOffset)
, m_kind(kind)
+ , m_jitType(jitType)
{
if (m_kind == ArgumentsEscaped) {
// Count this one globally. It doesn't matter where in the code block the arguments excaped;
@@ -61,9 +65,10 @@ public:
// Use this constructor if you wish for the exit site to be counted globally within its
// code block.
- explicit FrequentExitSite(ExitKind kind)
+ explicit FrequentExitSite(ExitKind kind, ExitingJITType jitType = ExitFromAnything)
: m_bytecodeOffset(0)
, m_kind(kind)
+ , m_jitType(jitType)
{
}
@@ -75,25 +80,48 @@ public:
bool operator==(const FrequentExitSite& other) const
{
return m_bytecodeOffset == other.m_bytecodeOffset
- && m_kind == other.m_kind;
+ && m_kind == other.m_kind
+ && m_jitType == other.m_jitType;
+ }
+
+ bool subsumes(const FrequentExitSite& other) const
+ {
+ if (m_bytecodeOffset != other.m_bytecodeOffset)
+ return false;
+ if (m_kind != other.m_kind)
+ return false;
+ if (m_jitType == ExitFromAnything)
+ return true;
+ return m_jitType == other.m_jitType;
}
unsigned hash() const
{
- return WTF::intHash(m_bytecodeOffset) + m_kind;
+ return WTF::intHash(m_bytecodeOffset) + m_kind + m_jitType * 7;
}
unsigned bytecodeOffset() const { return m_bytecodeOffset; }
ExitKind kind() const { return m_kind; }
+ ExitingJITType jitType() const { return m_jitType; }
+
+ FrequentExitSite withJITType(ExitingJITType jitType) const
+ {
+ FrequentExitSite result = *this;
+ result.m_jitType = jitType;
+ return result;
+ }
bool isHashTableDeletedValue() const
{
return m_kind == ExitKindUnset && m_bytecodeOffset;
}
+
+ void dump(PrintStream& out) const;
private:
unsigned m_bytecodeOffset;
ExitKind m_kind;
+ ExitingJITType m_jitType;
};
struct FrequentExitSiteHash {
@@ -104,6 +132,7 @@ struct FrequentExitSiteHash {
} } // namespace JSC::DFG
+
namespace WTF {
template<typename T> struct DefaultHash;
@@ -131,7 +160,7 @@ public:
// be called a fixed number of times per recompilation. Recompilation is
// rare to begin with, and implies doing O(n) operations on the CodeBlock
// anyway.
- bool add(const ConcurrentJITLocker&, const FrequentExitSite&);
+ bool add(const ConcurrentJSLocker&, CodeBlock* owner, const FrequentExitSite&);
// Get the frequent exit sites for a bytecode index. This is O(n), and is
// meant to only be used from debugging/profiling code.
@@ -141,12 +170,12 @@ public:
// in the compiler. It should be strictly cheaper than building a
// QueryableExitProfile, if you really expect this to be called infrequently
// and you believe that there are few exit sites.
- bool hasExitSite(const ConcurrentJITLocker&, const FrequentExitSite&) const;
- bool hasExitSite(const ConcurrentJITLocker& locker, ExitKind kind) const
+ bool hasExitSite(const ConcurrentJSLocker&, const FrequentExitSite&) const;
+ bool hasExitSite(const ConcurrentJSLocker& locker, ExitKind kind) const
{
return hasExitSite(locker, FrequentExitSite(kind));
}
- bool hasExitSite(const ConcurrentJITLocker& locker, unsigned bytecodeIndex, ExitKind kind) const
+ bool hasExitSite(const ConcurrentJSLocker& locker, unsigned bytecodeIndex, ExitKind kind) const
{
return hasExitSite(locker, FrequentExitSite(bytecodeIndex, kind));
}
@@ -154,7 +183,7 @@ public:
private:
friend class QueryableExitProfile;
- OwnPtr<Vector<FrequentExitSite>> m_frequentExitSites;
+ std::unique_ptr<Vector<FrequentExitSite>> m_frequentExitSites;
};
class QueryableExitProfile {
@@ -162,10 +191,14 @@ public:
QueryableExitProfile();
~QueryableExitProfile();
- void initialize(const ConcurrentJITLocker&, const ExitProfile&);
+ void initialize(const ConcurrentJSLocker&, const ExitProfile&);
bool hasExitSite(const FrequentExitSite& site) const
{
+ if (site.jitType() == ExitFromAnything) {
+ return hasExitSite(site.withJITType(ExitFromDFG))
+ || hasExitSite(site.withJITType(ExitFromFTL));
+ }
return m_frequentExitSites.find(site) != m_frequentExitSites.end();
}
@@ -184,4 +217,4 @@ private:
} } // namespace JSC::DFG
-#endif // DFGExitProfile_h
+#endif // ENABLE(DFG_JIT)