]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * Copyright (C) 2012, 2013, 2015 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 | * | |
8 | * 1. Redistributions of source code must retain the above copyright | |
9 | * notice, this list of conditions and the following disclaimer. | |
10 | * 2. Redistributions in binary form must reproduce the above copyright | |
11 | * notice, this list of conditions and the following disclaimer in the | |
12 | * documentation and/or other materials provided with the distribution. | |
13 | * 3. Neither the name of Apple Inc. ("Apple") nor the names of | |
14 | * its contributors may be used to endorse or promote products derived | |
15 | * from this software without specific prior written permission. | |
16 | * | |
17 | * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY | |
18 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
19 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
20 | * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY | |
21 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
22 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
23 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
24 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
27 | */ | |
28 | ||
29 | #ifndef JSSegmentedVariableObject_h | |
30 | #define JSSegmentedVariableObject_h | |
31 | ||
32 | #include "ConcurrentJITLock.h" | |
33 | #include "JSObject.h" | |
34 | #include "JSSymbolTableObject.h" | |
35 | #include "Register.h" | |
36 | #include "SymbolTable.h" | |
37 | #include <wtf/SegmentedVector.h> | |
38 | ||
39 | namespace JSC { | |
40 | ||
41 | class LLIntOffsetsExtractor; | |
42 | class Register; | |
43 | ||
44 | // This is a mostly drop-in replacement for JSEnvironmentRecord, except that it preserves | |
45 | // the invariant that after a variable is created, its address in memory will not change | |
46 | // so long as the JSSegmentedVariableObject is alive. This allows optimizations based | |
47 | // on getting the address of the variable and remembering it. As well, unlike a | |
48 | // JSEnvironmentRecord, this will manage the memory for the registers itself and neither | |
49 | // requires nor allows for the subclasses to manage that memory. Finally, | |
50 | // JSSegmentedVariableObject has its own GC tracing functionality, since it knows the | |
51 | // exact dimensions of the variables array at all times. | |
52 | ||
53 | class JSSegmentedVariableObject : public JSSymbolTableObject { | |
54 | friend class JIT; | |
55 | friend class LLIntOffsetsExtractor; | |
56 | ||
57 | public: | |
58 | typedef JSSymbolTableObject Base; | |
59 | ||
60 | // This is not thread-safe, since m_variables is a segmented vector, and its spine can resize with | |
61 | // malloc/free if new variables - unrelated to the one you are accessing - are added. You can get | |
62 | // around this by grabbing m_lock, or finding some other way to get to the variable pointer (global | |
63 | // variable access bytecode instructions will have a direct pointer already). | |
64 | WriteBarrier<Unknown>& variableAt(ScopeOffset offset) { return m_variables[offset.offset()]; } | |
65 | ||
66 | // This is a slow method call, which searches the register bank to find the index | |
67 | // given a pointer. It will CRASH() if it does not find the register. Only use this | |
68 | // in debug code (like bytecode dumping). | |
69 | JS_EXPORT_PRIVATE ScopeOffset findVariableIndex(void*); | |
70 | ||
71 | WriteBarrier<Unknown>* assertVariableIsInThisObject(WriteBarrier<Unknown>* variablePointer) | |
72 | { | |
73 | if (!ASSERT_DISABLED) | |
74 | findVariableIndex(variablePointer); | |
75 | return variablePointer; | |
76 | } | |
77 | ||
78 | // Adds numberOfRegistersToAdd registers, initializes them to Undefined, and returns | |
79 | // the index of the first one added. | |
80 | JS_EXPORT_PRIVATE ScopeOffset addVariables(unsigned numberOfVariablesToAdd); | |
81 | ||
82 | JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&); | |
83 | ||
84 | protected: | |
85 | JSSegmentedVariableObject(VM& vm, Structure* structure, JSScope* scope) | |
86 | : JSSymbolTableObject(vm, structure, scope) | |
87 | { | |
88 | } | |
89 | ||
90 | void finishCreation(VM& vm) | |
91 | { | |
92 | Base::finishCreation(vm); | |
93 | setSymbolTable(vm, SymbolTable::create(vm)); | |
94 | } | |
95 | ||
96 | SegmentedVector<WriteBarrier<Unknown>, 16> m_variables; | |
97 | ConcurrentJITLock m_lock; | |
98 | }; | |
99 | ||
100 | } // namespace JSC | |
101 | ||
102 | #endif // JSSegmentedVariableObject_h | |
103 |