Index: src/debug.h |
=================================================================== |
--- src/debug.h (revision 1984) |
+++ src/debug.h (working copy) |
@@ -33,6 +33,7 @@ |
#include "debug-agent.h" |
#include "execution.h" |
#include "factory.h" |
+#include "hashmap.h" |
#include "platform.h" |
#include "string-stream.h" |
#include "v8threads.h" |
@@ -144,6 +145,42 @@ |
}; |
+// Cache of all script objects in the heap. When a script is added a weak handle |
+// to it is created and that weak handle is stored in the cache. The weak handle |
+// callback takes care of removing the script from the cache. The key used in |
+// the hash map holding the cache is the script id. |
Mads Ager (chromium)
2009/05/18 12:57:00
I would just write "The key used in the cache is t
Søren Thygesen Gjesse
2009/05/18 13:13:17
Done.
|
+class ScriptCache : private HashMap { |
+ public: |
+ ScriptCache() : HashMap(ScriptMatch), collected_scripts_(10) {} |
+ virtual ~ScriptCache() { Clear(); } |
+ |
+ // Add script to the cache. |
+ void Add(Handle<Script> script); |
+ |
+ // Return the scripts in the cache. |
+ Handle<FixedArray> GetScripts(); |
+ |
+ // Generate debugger events for collected scripts. |
+ void ProcessCollectedScripts(); |
+ |
+ private: |
+ // Calculate the hash value from the key (script id). |
+ static uint32_t Hash(int key) { return ComputeIntegerHash(key); } |
+ |
+ // Scripts match if their keys (script id) match. |
+ static bool ScriptMatch(void* key1, void* key2) { return key1 == key2; } |
+ |
+ // Clear the cache releasing all the weak handles. |
+ void Clear(); |
+ |
+ // Weak handle callback for scripts in the cache. |
+ static void HandleWeakScript(v8::Persistent<v8::Value> obj, void* data); |
+ |
+ // List used during GC to temporarily store id's of collected scripts. |
+ List<int> collected_scripts_; |
+}; |
+ |
+ |
// Linked list holding debug info objects. The debug info objects are kept as |
// weak handles to avoid a debug info object to keep a function alive. |
class DebugInfoListNode { |
@@ -230,9 +267,6 @@ |
} |
static int break_id() { return thread_local_.break_id_; } |
- |
- |
- |
static bool StepInActive() { return thread_local_.step_into_fp_ != 0; } |
static void HandleStepIn(Handle<JSFunction> function, |
Address fp, |
@@ -307,6 +341,15 @@ |
// Mirror cache handling. |
static void ClearMirrorCache(); |
+ // Script cache handling. |
+ static void CreateScriptCache(); |
+ static void DestroyScriptCache(); |
+ static void AddScriptToScriptCache(Handle<Script> script); |
+ static Handle<FixedArray> GetLoadedScripts(); |
+ |
+ // Garbage collection notifications. |
+ static void AfterGarbageCollection(); |
+ |
// Code generation assumptions. |
static const int kIa32CallInstructionLength = 5; |
static const int kIa32JSReturnSequenceLength = 6; |
@@ -343,6 +386,11 @@ |
// Boolean state indicating whether any break points are set. |
static bool has_break_points_; |
+ |
+ // Cache of all scripts in the heap. |
+ static ScriptCache* script_cache_; |
+ |
+ // List of active debug info objects. |
static DebugInfoListNode* debug_info_list_; |
static bool disable_break_; |
@@ -532,12 +580,15 @@ |
static Handle<Object> MakeCompileEvent(Handle<Script> script, |
bool before, |
bool* caught_exception); |
+ static Handle<Object> MakeScriptCollectedEvent(int id, |
+ bool* caught_exception); |
static void OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue); |
static void OnException(Handle<Object> exception, bool uncaught); |
static void OnBeforeCompile(Handle<Script> script); |
static void OnAfterCompile(Handle<Script> script, |
Handle<JSFunction> fun); |
static void OnNewFunction(Handle<JSFunction> fun); |
+ static void OnScriptCollected(int id); |
static void ProcessDebugEvent(v8::DebugEvent event, |
Handle<JSObject> event_data, |
bool auto_continue); |
@@ -670,8 +721,15 @@ |
StackGuard::DebugCommand(); |
} |
- // If leaving the debugger with the debugger no longer active unload it. |
if (prev_ == NULL) { |
+ // Clear mirror cache when leaving the debugger. Skip this if there is a |
+ // pending exception as clearing the mirror cache calls back into |
+ // JavaScript. This can happen if the v8::Debug::Call is used in which |
+ // case the exception should end up in the calling code. |
+ if (!Top::has_pending_exception()) { |
+ Debug::ClearMirrorCache(); |
+ } |
+ // If leaving the debugger with the debugger no longer active unload it. |
if (!Debugger::IsDebuggerActive()) { |
Debugger::UnloadDebugger(); |
} |