1/*
2 * Copyright (C) 2014 Apple Inc. All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#include "TypeLocation.h"
29#include "TypeLocationCache.h"
30#include <wtf/Bag.h>
31#include <wtf/HashMap.h>
32#include <wtf/Vector.h>
33#include <wtf/text/WTFString.h>
34
35namespace Inspector { namespace Protocol { namespace Runtime {
36class TypeDescription;
37}}}
38
39namespace JSC {
40
41enum TypeProfilerSearchDescriptor {
42 TypeProfilerSearchDescriptorNormal = 1,
43 TypeProfilerSearchDescriptorFunctionReturn = 2
44};
45
46struct QueryKey {
47 QueryKey()
48 : m_sourceID(0)
49 , m_divot(0)
50 , m_searchDescriptor(TypeProfilerSearchDescriptorFunctionReturn)
51 { }
52
53 QueryKey(intptr_t sourceID, unsigned divot, TypeProfilerSearchDescriptor searchDescriptor)
54 : m_sourceID(sourceID)
55 , m_divot(divot)
56 , m_searchDescriptor(searchDescriptor)
57 { }
58
59 QueryKey(WTF::HashTableDeletedValueType)
60 : m_sourceID(INTPTR_MAX)
61 , m_divot(UINT_MAX)
62 , m_searchDescriptor(TypeProfilerSearchDescriptorFunctionReturn)
63 { }
64
65 bool isHashTableDeletedValue() const
66 {
67 return m_sourceID == INTPTR_MAX
68 && m_divot == UINT_MAX
69 && m_searchDescriptor == TypeProfilerSearchDescriptorFunctionReturn;
70 }
71
72 bool operator==(const QueryKey& other) const
73 {
74 return m_sourceID == other.m_sourceID
75 && m_divot == other.m_divot
76 && m_searchDescriptor == other.m_searchDescriptor;
77 }
78
79 unsigned hash() const
80 {
81 unsigned hash = m_sourceID + m_divot * m_searchDescriptor;
82 return hash;
83 }
84
85 intptr_t m_sourceID;
86 unsigned m_divot;
87 TypeProfilerSearchDescriptor m_searchDescriptor;
88};
89
90struct QueryKeyHash {
91 static unsigned hash(const QueryKey& key) { return key.hash(); }
92 static bool equal(const QueryKey& a, const QueryKey& b) { return a == b; }
93 static const bool safeToCompareToEmptyOrDeleted = true;
94};
95
96} // namespace JSC
97
98namespace WTF {
99
100template<typename T> struct DefaultHash;
101template<> struct DefaultHash<JSC::QueryKey> {
102 typedef JSC::QueryKeyHash Hash;
103};
104
105template<typename T> struct HashTraits;
106template<> struct HashTraits<JSC::QueryKey> : SimpleClassHashTraits<JSC::QueryKey> {
107 static const bool emptyValueIsZero = false;
108};
109
110} // namespace WTF
111
112namespace JSC {
113
114class VM;
115
116class TypeProfiler {
117 WTF_MAKE_FAST_ALLOCATED;
118public:
119 TypeProfiler();
120 void logTypesForTypeLocation(TypeLocation*, VM&);
121 JS_EXPORT_PRIVATE String typeInformationForExpressionAtOffset(TypeProfilerSearchDescriptor, unsigned offset, intptr_t sourceID, VM&);
122 void insertNewLocation(TypeLocation*);
123 TypeLocationCache* typeLocationCache() { return &m_typeLocationCache; }
124 TypeLocation* findLocation(unsigned divot, intptr_t sourceID, TypeProfilerSearchDescriptor, VM&);
125 GlobalVariableID getNextUniqueVariableID() { return m_nextUniqueVariableID++; }
126 TypeLocation* nextTypeLocation();
127 void invalidateTypeSetCache(VM&);
128 void dumpTypeProfilerData(VM&);
129
130private:
131 typedef HashMap<intptr_t, Vector<TypeLocation*>> SourceIDToLocationBucketMap;
132 SourceIDToLocationBucketMap m_bucketMap;
133 TypeLocationCache m_typeLocationCache;
134 typedef HashMap<QueryKey, TypeLocation*> TypeLocationQueryCache;
135 TypeLocationQueryCache m_queryCache;
136 GlobalVariableID m_nextUniqueVariableID;
137 Bag<TypeLocation> m_typeLocationInfo;
138};
139
140} // namespace JSC
141