Commit 88000d03 authored by yangguo@chromium.org's avatar yangguo@chromium.org

Fix debugger-related issues in the code serializer.

R=mvstanton@chromium.org

Review URL: https://codereview.chromium.org/410883003

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22543 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 37ebdc7d
......@@ -961,7 +961,8 @@ Handle<SharedFunctionInfo> Compiler::CompileScript(
Handle<SharedFunctionInfo> result;
if (extension == NULL) {
if (FLAG_serialize_toplevel &&
compile_options == ScriptCompiler::kConsumeCodeCache) {
compile_options == ScriptCompiler::kConsumeCodeCache &&
!isolate->debug()->is_loaded()) {
return CodeSerializer::Deserialize(isolate, *cached_data, source);
} else {
maybe_result = compilation_cache->LookupScript(
......
......@@ -622,7 +622,14 @@ void ScriptCache::Add(Handle<Script> script) {
HashMap::Entry* entry =
HashMap::Lookup(reinterpret_cast<void*>(id), Hash(id), true);
if (entry->value != NULL) {
ASSERT(*script == *reinterpret_cast<Script**>(entry->value));
#ifdef DEBUG
// The code deserializer may introduce duplicate Script objects.
// Assert that the Script objects with the same id have the same name.
Handle<Script> found(reinterpret_cast<Script**>(entry->value));
ASSERT(script->id() == found->id());
ASSERT(!script->name()->IsString() ||
String::cast(script->name())->Equals(String::cast(found->name())));
#endif
return;
}
// Globalize the script object, make it weak and use the location of the
......
......@@ -10284,16 +10284,21 @@ Handle<Object> Script::GetNameOrSourceURL(Handle<Script> script) {
// collector will call the weak callback on the global handle
// associated with the wrapper and get rid of both the wrapper and the
// handle.
static void ClearWrapperCache(
static void ClearWrapperCacheWeakCallback(
const v8::WeakCallbackData<v8::Value, void>& data) {
Object** location = reinterpret_cast<Object**>(data.GetParameter());
JSValue* wrapper = JSValue::cast(*location);
Foreign* foreign = Script::cast(wrapper->value())->wrapper();
Script::cast(wrapper->value())->ClearWrapperCache();
}
void Script::ClearWrapperCache() {
Foreign* foreign = wrapper();
Object** location = reinterpret_cast<Object**>(foreign->foreign_address());
ASSERT_EQ(foreign->foreign_address(), reinterpret_cast<Address>(location));
foreign->set_foreign_address(0);
GlobalHandles::Destroy(location);
Isolate* isolate = reinterpret_cast<Isolate*>(data.GetIsolate());
isolate->counters()->script_wrappers()->Decrement();
GetIsolate()->counters()->script_wrappers()->Decrement();
}
......@@ -10318,7 +10323,7 @@ Handle<JSObject> Script::GetWrapper(Handle<Script> script) {
Handle<Object> handle = isolate->global_handles()->Create(*result);
GlobalHandles::MakeWeak(handle.location(),
reinterpret_cast<void*>(handle.location()),
&ClearWrapperCache);
&ClearWrapperCacheWeakCallback);
script->wrapper()->set_foreign_address(
reinterpret_cast<Address>(handle.location()));
return result;
......
......@@ -6934,6 +6934,7 @@ class Script: public Struct {
// Get the JS object wrapping the given script; create it if none exists.
static Handle<JSObject> GetWrapper(Handle<Script> script);
void ClearWrapperCache();
// Dispatched behavior.
DECLARE_PRINTER(Script)
......
......@@ -1962,6 +1962,13 @@ void CodeSerializer::SerializeObject(Object* o, HowToCode how_to_code,
return;
}
if (heap_object->IsScript()) {
// The wrapper cache uses a Foreign object to point to a global handle.
// However, the object visitor expects foreign objects to point to external
// references. Clear the cache to avoid this issue.
Script::cast(heap_object)->ClearWrapperCache();
}
if (skip != 0) {
sink_->Put(kSkip, "SkipFromSerializeObject");
sink_->PutInt(skip, "SkipDistanceFromSerializeObject");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment