13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2011 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_EXECUTION_H_ 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_EXECUTION_H_ 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 31257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "allocation.h" 32257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Flag used to set the interrupt causes. 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockenum InterruptFlag { 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block INTERRUPT = 1 << 0, 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DEBUGBREAK = 1 << 1, 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DEBUGCOMMAND = 1 << 2, 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PREEMPT = 1 << 3, 43b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch TERMINATE = 1 << 4, 443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RUNTIME_PROFILER_TICK = 1 << 5, 453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GC_REQUEST = 1 << 6 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass Isolate; 503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Execution : public AllStatic { 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call a function, the caller supplies a receiver and an array 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // of arguments. Arguments are Object* type. After function returns, 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // pointers in 'args' might be invalid. 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // *pending_exception tells whether the invoke resulted in 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // a pending exception. 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 61589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // When convert_receiver is set, and the receiver is not an object, 62589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // and the function called is not in strict mode, receiver is converted to 63589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // an object. 64589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // 65257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static Handle<Object> Call(Handle<Object> callable, 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> receiver, 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int argc, 683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> argv[], 69589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch bool* pending_exception, 70589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch bool convert_receiver = false); 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Construct object from function, the caller supplies an array of 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // arguments. Arguments are Object* type. After function returns, 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // pointers in 'args' might be invalid. 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // *pending_exception tells whether the invoke resulted in 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // a pending exception. 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Handle<Object> New(Handle<JSFunction> func, 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int argc, 813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> argv[], 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* pending_exception); 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call a function, just like Call(), but make sure to silently catch 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // any thrown exceptions. The return value is either the result of 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // calling the function (if caught exception is false) or the exception 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // that occurred (if caught exception is true). 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Handle<Object> TryCall(Handle<JSFunction> func, 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> receiver, 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int argc, 913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> argv[], 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* caught_exception); 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ECMA-262 9.2 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Handle<Object> ToBoolean(Handle<Object> obj); 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ECMA-262 9.3 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Handle<Object> ToNumber(Handle<Object> obj, bool* exc); 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ECMA-262 9.4 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Handle<Object> ToInteger(Handle<Object> obj, bool* exc); 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ECMA-262 9.5 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Handle<Object> ToInt32(Handle<Object> obj, bool* exc); 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ECMA-262 9.6 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Handle<Object> ToUint32(Handle<Object> obj, bool* exc); 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ECMA-262 9.8 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Handle<Object> ToString(Handle<Object> obj, bool* exc); 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ECMA-262 9.8 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Handle<Object> ToDetailString(Handle<Object> obj, bool* exc); 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ECMA-262 9.9 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Handle<Object> ToObject(Handle<Object> obj, bool* exc); 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a new date object from 'time'. 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Handle<Object> NewDate(double time, bool* exc); 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 121f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Create a new regular expression object from 'pattern' and 'flags'. 122f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch static Handle<JSRegExp> NewJSRegExp(Handle<String> pattern, 123f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Handle<String> flags, 124f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch bool* exc); 125f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Used to implement [] notation on strings (calls JS code) 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Handle<Object> CharAt(Handle<String> str, uint32_t index); 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Handle<Object> GetFunctionFor(); 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Handle<JSFunction> InstantiateFunction( 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<FunctionTemplateInfo> data, bool* exc); 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Handle<JSObject> InstantiateObject(Handle<ObjectTemplateInfo> data, 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* exc); 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void ConfigureInstance(Handle<Object> instance, 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> data, 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* exc); 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Handle<String> GetStackTraceLine(Handle<Object> recv, 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSFunction> fun, 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> pos, 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> is_global); 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Object* DebugBreakHelper(); 1433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void ProcessDebugMessages(bool debug_command_only); 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the stack guard is triggered, but it is not an actual 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // stack overflow, then handle the interruption accordingly. 1483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MUST_USE_RESULT static MaybeObject* HandleStackGuardInterrupt( 1493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Isolate* isolate); 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get a function delegate (or undefined) for the given non-function 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // object. Used for support calling objects as functions. 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Handle<Object> GetFunctionDelegate(Handle<Object> object); 154257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static Handle<Object> TryGetFunctionDelegate(Handle<Object> object, 155257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bool* has_pending_exception); 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get a function delegate (or undefined) for the given non-function 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // object. Used for support calling objects as constructors. 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Handle<Object> GetConstructorDelegate(Handle<Object> object); 160257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static Handle<Object> TryGetConstructorDelegate(Handle<Object> object, 161257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bool* has_pending_exception); 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ExecutionAccess; 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// StackGuard contains the handling of the limits that are used to limit the 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// number of nested invocations of JavaScript and the stack size used in each 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// invocation. 17144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass StackGuard { 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Pass the address beyond which the stack should not grow. The stack 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is assumed to grow downwards. 17544f0eee88ff00398ff7f715fab053374d808c90dSteve Block void SetStackLimit(uintptr_t limit); 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Threading support. 17844f0eee88ff00398ff7f715fab053374d808c90dSteve Block char* ArchiveStackGuard(char* to); 17944f0eee88ff00398ff7f715fab053374d808c90dSteve Block char* RestoreStackGuard(char* from); 18044f0eee88ff00398ff7f715fab053374d808c90dSteve Block static int ArchiveSpacePerThread() { return sizeof(ThreadLocal); } 18144f0eee88ff00398ff7f715fab053374d808c90dSteve Block void FreeThreadResources(); 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Sets up the default stack guard for this thread if it has not 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // already been set up. 18444f0eee88ff00398ff7f715fab053374d808c90dSteve Block void InitThread(const ExecutionAccess& lock); 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clears the stack guard for this thread so it does not look as if 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // it has been set up. 18744f0eee88ff00398ff7f715fab053374d808c90dSteve Block void ClearThread(const ExecutionAccess& lock); 18844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 18944f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool IsStackOverflow(); 19044f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool IsPreempted(); 19144f0eee88ff00398ff7f715fab053374d808c90dSteve Block void Preempt(); 19244f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool IsInterrupted(); 19344f0eee88ff00398ff7f715fab053374d808c90dSteve Block void Interrupt(); 19444f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool IsTerminateExecution(); 19544f0eee88ff00398ff7f715fab053374d808c90dSteve Block void TerminateExecution(); 19644f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool IsRuntimeProfilerTick(); 19744f0eee88ff00398ff7f715fab053374d808c90dSteve Block void RequestRuntimeProfilerTick(); 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 19944f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool IsDebugBreak(); 20044f0eee88ff00398ff7f715fab053374d808c90dSteve Block void DebugBreak(); 20144f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool IsDebugCommand(); 20244f0eee88ff00398ff7f715fab053374d808c90dSteve Block void DebugCommand(); 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 2043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool IsGCRequest(); 2053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void RequestGC(); 20644f0eee88ff00398ff7f715fab053374d808c90dSteve Block void Continue(InterruptFlag after_what); 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 208d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // This provides an asynchronous read of the stack limits for the current 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // thread. There are no locks protecting this, but it is assumed that you 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // have the global V8 lock if you are using multiple V8 threads. 21144f0eee88ff00398ff7f715fab053374d808c90dSteve Block uintptr_t climit() { 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return thread_local_.climit_; 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 21444f0eee88ff00398ff7f715fab053374d808c90dSteve Block uintptr_t real_climit() { 2158a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang return thread_local_.real_climit_; 2168a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang } 21744f0eee88ff00398ff7f715fab053374d808c90dSteve Block uintptr_t jslimit() { 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return thread_local_.jslimit_; 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 22044f0eee88ff00398ff7f715fab053374d808c90dSteve Block uintptr_t real_jslimit() { 221d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return thread_local_.real_jslimit_; 222d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 22344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Address address_of_jslimit() { 224d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return reinterpret_cast<Address>(&thread_local_.jslimit_); 225d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 22644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Address address_of_real_jslimit() { 227d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return reinterpret_cast<Address>(&thread_local_.real_jslimit_); 228d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 2293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool ShouldPostponeInterrupts(); 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 23244f0eee88ff00398ff7f715fab053374d808c90dSteve Block StackGuard(); 23344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // You should hold the ExecutionAccess lock when calling this method. 23544f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool has_pending_interrupts(const ExecutionAccess& lock) { 2366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Sanity check: We shouldn't be asking about pending interrupts 2376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // unless we're not postponing them anymore. 2386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ASSERT(!should_postpone_interrupts(lock)); 2396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return thread_local_.interrupt_flags_ != 0; 2406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 2416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // You should hold the ExecutionAccess lock when calling this method. 24344f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool should_postpone_interrupts(const ExecutionAccess& lock) { 2446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return thread_local_.postpone_interrupts_nesting_ > 0; 2456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // You should hold the ExecutionAccess lock when calling this method. 24844f0eee88ff00398ff7f715fab053374d808c90dSteve Block inline void set_interrupt_limits(const ExecutionAccess& lock); 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 250d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Reset limits to actual values. For example after handling interrupt. 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // You should hold the ExecutionAccess lock when calling this method. 25244f0eee88ff00398ff7f715fab053374d808c90dSteve Block inline void reset_limits(const ExecutionAccess& lock); 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Enable or disable interrupts. 25544f0eee88ff00398ff7f715fab053374d808c90dSteve Block void EnableInterrupts(); 25644f0eee88ff00398ff7f715fab053374d808c90dSteve Block void DisableInterrupts(); 257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef V8_TARGET_ARCH_X64 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const uintptr_t kInterruptLimit = V8_UINT64_C(0xfffffffffffffffe); 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const uintptr_t kIllegalLimit = V8_UINT64_C(0xfffffffffffffff8); 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#else 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const uintptr_t kInterruptLimit = 0xfffffffe; 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const uintptr_t kIllegalLimit = 0xfffffff8; 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block class ThreadLocal { 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ThreadLocal() { Clear(); } 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // You should hold the ExecutionAccess lock when you call Initialize or 270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear. 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Clear(); 272d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 27344f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Returns true if the heap's stack limits should be set, false if not. 274257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bool Initialize(Isolate* isolate); 27544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 276d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // The stack limit is split into a JavaScript and a C++ stack limit. These 277d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // two are the same except when running on a simulator where the C++ and 278d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // JavaScript stacks are separate. Each of the two stack limits have two 279d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // values. The one eith the real_ prefix is the actual stack limit 280d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // set for the VM. The one without the real_ prefix has the same value as 281d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // the actual stack limit except when there is an interruption (e.g. debug 282d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // break or preemption) in which case it is lowered to make stack checks 283d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // fail. Both the generated code and the runtime system check against the 284d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // one without the real_ prefix. 285d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block uintptr_t real_jslimit_; // Actual JavaScript stack limit set for the VM. 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uintptr_t jslimit_; 287d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block uintptr_t real_climit_; // Actual C++ stack limit set for the VM. 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uintptr_t climit_; 289d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int nesting_; 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int postpone_interrupts_nesting_; 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int interrupt_flags_; 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 29544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // TODO(isolates): Technically this could be calculated directly from a 29644f0eee88ff00398ff7f715fab053374d808c90dSteve Block // pointer to StackGuard. 29744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate_; 29844f0eee88ff00398ff7f715fab053374d808c90dSteve Block ThreadLocal thread_local_; 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 30044f0eee88ff00398ff7f715fab053374d808c90dSteve Block friend class Isolate; 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackLimitCheck; 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class PostponeInterruptsScope; 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 30444f0eee88ff00398ff7f715fab053374d808c90dSteve Block DISALLOW_COPY_AND_ASSIGN(StackGuard); 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_EXECUTION_H_ 311