source: webkit/trunk/JavaScriptCore/VM/Machine.h@ 34842

Last change on this file since 34842 was 34842, checked in by [email protected], 17 years ago

Bug 18626: SQUIRRELFISH: support the "slow script" dialog <https://bugs.webkit.org/show_bug.cgi?id=18626>
<rdar://problem/5973931> Slow script dialog needs to be reimplemented for squirrelfish

Reviewed by Sam

Adds support for the slow script dialog in squirrelfish. This requires the addition
of three new op codes, op_loop, op_loop_if_true, and op_loop_if_less which have the
same behaviour as their simple jump equivalents but have an additional time out check.

Additional assertions were added to other jump instructions to prevent accidentally
creating loops with jump types that do not support time out checks.

Sunspider does not report a regression, however this appears very sensitive to code
layout and hardware, so i would expect up to a 1% regression on other systems.

Part of this required moving the old timeout logic from JSGlobalObject and into Machine
which is the cause of a number of the larger diff blocks.

File size: 6.0 KB
Line 
1/*
2 * Copyright (C) 2008 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 Computer, 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 Machine_h
30#define Machine_h
31
32#include "Opcode.h"
33#include "RegisterFile.h"
34#include <kjs/list.h>
35#include <wtf/HashMap.h>
36
37namespace KJS {
38
39 class CodeBlock;
40 class EvalNode;
41 class ExecState;
42 class FunctionBodyNode;
43 class Instruction;
44 class JSFunction;
45 class JSGlobalObject;
46 class ProgramNode;
47 class Register;
48 class RegisterFile;
49 class ScopeChainNode;
50
51 enum DebugHookID {
52 WillExecuteProgram,
53 DidExecuteProgram,
54 DidEnterCallFrame,
55 DidReachBreakpoint,
56 WillLeaveCallFrame,
57 WillExecuteStatement
58 };
59
60 enum { MaxReentryDepth = 128 };
61
62 class Machine {
63 public:
64 Machine();
65
66 RegisterFile& registerFile() { return m_registerFile; }
67
68 Opcode getOpcode(OpcodeID id)
69 {
70 #if HAVE(COMPUTED_GOTO)
71 return m_opcodeTable[id];
72 #else
73 return id;
74 #endif
75 }
76
77 OpcodeID getOpcodeID(Opcode opcode)
78 {
79 #if HAVE(COMPUTED_GOTO)
80 ASSERT(isOpcode(opcode));
81 return m_opcodeIDTable.get(opcode);
82 #else
83 return opcode;
84 #endif
85 }
86
87 bool isOpcode(Opcode opcode);
88
89 JSValue* execute(ProgramNode*, ExecState*, ScopeChainNode*, JSObject* thisObj, JSValue** exception);
90 JSValue* execute(FunctionBodyNode*, ExecState*, JSFunction*, JSObject* thisObj, const ArgList& args, ScopeChainNode*, JSValue** exception);
91 JSValue* execute(EvalNode* evalNode, ExecState* exec, JSObject* thisObj, ScopeChainNode* scopeChain, JSValue** exception)
92 {
93 return execute(evalNode, exec, thisObj, m_registerFile.size(), scopeChain, exception);
94 }
95
96 JSValue* retrieveArguments(ExecState*, JSFunction*) const;
97 JSValue* retrieveCaller(ExecState*, JSFunction*) const;
98
99 void getFunctionAndArguments(Register** registerBase, Register* callFrame, JSFunction*&, Register*& argv, int& argc);
100 void setTimeoutTime(unsigned timeoutTime) { m_timeoutTime = timeoutTime; }
101
102 void startTimeoutCheck()
103 {
104 if (!m_timeoutCheckCount)
105 resetTimeoutCheck();
106
107 ++m_timeoutCheckCount;
108 }
109
110 void stopTimeoutCheck()
111 {
112 --m_timeoutCheckCount;
113 }
114
115 inline void initTimeout()
116 {
117 resetTimeoutCheck();
118 m_timeoutTime = 0;
119 m_timeoutCheckCount = 0;
120 }
121 void mark(Heap* heap) { m_registerFile.mark(heap); }
122
123 private:
124 enum ExecutionFlag { Normal, InitializeAndReturn };
125
126 friend NEVER_INLINE JSValue* callEval(ExecState* exec, JSObject* thisObj, ScopeChainNode* scopeChain, RegisterFile*, Register* r, int argv, int argc, JSValue*& exceptionValue);
127 JSValue* execute(EvalNode*, ExecState*, JSObject* thisObj, int registerOffset, ScopeChainNode*, JSValue** exception);
128
129 ALWAYS_INLINE void setScopeChain(ExecState* exec, ScopeChainNode*&, ScopeChainNode*);
130 NEVER_INLINE void debug(ExecState*, const Instruction*, const CodeBlock*, ScopeChainNode*, Register**, Register*);
131
132 NEVER_INLINE bool unwindCallFrame(ExecState*, JSValue*, Register**, const Instruction*&, CodeBlock*&, JSValue**&, ScopeChainNode*&, Register*&);
133 NEVER_INLINE Instruction* throwException(ExecState*, JSValue*, Register**, const Instruction*, CodeBlock*&, JSValue**&, ScopeChainNode*&, Register*&);
134
135 bool getCallFrame(ExecState*, JSFunction*, Register**& registerBase, int& callFrameOffset) const;
136
137 JSValue* privateExecute(ExecutionFlag, ExecState* = 0, RegisterFile* = 0, Register* = 0, ScopeChainNode* = 0, CodeBlock* = 0, JSValue** exception = 0);
138
139 void dumpCallFrame(const CodeBlock*, ScopeChainNode*, RegisterFile*, const Register*);
140 void dumpRegisters(const CodeBlock*, RegisterFile*, const Register*);
141
142 JSValue* checkTimeout(JSGlobalObject*);
143 void resetTimeoutCheck();
144
145 int m_reentryDepth;
146 unsigned m_timeoutTime;
147 unsigned m_timeAtLastCheckTimeout;
148 unsigned m_timeExecuting;
149 unsigned m_timeoutCheckCount;
150 unsigned m_ticksUntilNextTimeoutCheck;
151
152 RegisterFile m_registerFile;
153
154#if HAVE(COMPUTED_GOTO)
155 Opcode m_opcodeTable[numOpcodeIDs]; // Maps OpcodeID => Opcode for compiling
156 HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
157#endif
158 };
159
160} // namespace KJS
161
162#endif // Machine_h
Note: See TracBrowser for help on using the repository browser.