Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: src/objects.cc

Issue 659513003: Use WeakCell to handle the script wrapper cache (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Remove special handling during serialization Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <sstream> 5 #include <sstream>
6 6
7 #include "src/v8.h" 7 #include "src/v8.h"
8 8
9 #include "src/accessors.h" 9 #include "src/accessors.h"
10 #include "src/allocation-site-scopes.h" 10 #include "src/allocation-site-scopes.h"
(...skipping 9709 matching lines...) Expand 10 before | Expand all | Expand 10 after
9720 Handle<Object> result; 9720 Handle<Object> result;
9721 // Do not check against pending exception, since this function may be called 9721 // Do not check against pending exception, since this function may be called
9722 // when an exception has already been pending. 9722 // when an exception has already been pending.
9723 if (!Execution::TryCall(method, script_wrapper, 0, NULL).ToHandle(&result)) { 9723 if (!Execution::TryCall(method, script_wrapper, 0, NULL).ToHandle(&result)) {
9724 return isolate->factory()->undefined_value(); 9724 return isolate->factory()->undefined_value();
9725 } 9725 }
9726 return result; 9726 return result;
9727 } 9727 }
9728 9728
9729 9729
9730 // Wrappers for scripts are kept alive and cached in weak global
9731 // handles referred from foreign objects held by the scripts as long as
9732 // they are used. When they are not used anymore, the garbage
9733 // collector will call the weak callback on the global handle
9734 // associated with the wrapper and get rid of both the wrapper and the
9735 // handle.
9736 static void ClearWrapperCacheWeakCallback(
9737 const v8::WeakCallbackData<v8::Value, void>& data) {
9738 Object** location = reinterpret_cast<Object**>(data.GetParameter());
9739 JSValue* wrapper = JSValue::cast(*location);
9740 Script::cast(wrapper->value())->ClearWrapperCache();
9741 }
9742
9743
9744 void Script::ClearWrapperCache() {
9745 Foreign* foreign = wrapper();
9746 Object** location = reinterpret_cast<Object**>(foreign->foreign_address());
9747 DCHECK_EQ(foreign->foreign_address(), reinterpret_cast<Address>(location));
9748 foreign->set_foreign_address(0);
9749 GlobalHandles::Destroy(location);
9750 GetIsolate()->counters()->script_wrappers()->Decrement();
9751 }
9752
9753
9754 Handle<JSObject> Script::GetWrapper(Handle<Script> script) { 9730 Handle<JSObject> Script::GetWrapper(Handle<Script> script) {
9755 if (script->wrapper()->foreign_address() != NULL) { 9731 Isolate* isolate = script->GetIsolate();
9756 // Return a handle for the existing script wrapper from the cache. 9732 if (!script->wrapper()->IsUndefined()) {
9757 return Handle<JSValue>( 9733 Handle<WeakCell> cell(WeakCell::cast(script->wrapper()));
9758 *reinterpret_cast<JSValue**>(script->wrapper()->foreign_address())); 9734 if (!cell->value()->IsUndefined()) {
9735 // Return a handle for the existing script wrapper from the cache.
9736 return handle(JSObject::cast(cell->value()));
9737 }
9738 // If we found an empty WeakCell, that means the script wrapper was
9739 // GCed. We are not notified directly of that, so we decrement here
9740 // so that we at least don't count double for any given script.
9741 isolate->counters()->script_wrappers()->Decrement();
9759 } 9742 }
9760 Isolate* isolate = script->GetIsolate();
9761 // Construct a new script wrapper. 9743 // Construct a new script wrapper.
9762 isolate->counters()->script_wrappers()->Increment(); 9744 isolate->counters()->script_wrappers()->Increment();
9763 Handle<JSFunction> constructor = isolate->script_function(); 9745 Handle<JSFunction> constructor = isolate->script_function();
9764 Handle<JSValue> result = 9746 Handle<JSValue> result =
9765 Handle<JSValue>::cast(isolate->factory()->NewJSObject(constructor)); 9747 Handle<JSValue>::cast(isolate->factory()->NewJSObject(constructor));
9766
9767 result->set_value(*script); 9748 result->set_value(*script);
9768 9749 Handle<WeakCell> cell = isolate->factory()->NewWeakCell(result);
9769 // Create a new weak global handle and use it to cache the wrapper 9750 script->set_wrapper(*cell);
9770 // for future use. The cache will automatically be cleared by the
9771 // garbage collector when it is not used anymore.
9772 Handle<Object> handle = isolate->global_handles()->Create(*result);
9773 GlobalHandles::MakeWeak(handle.location(),
9774 reinterpret_cast<void*>(handle.location()),
9775 &ClearWrapperCacheWeakCallback);
9776 script->wrapper()->set_foreign_address(
9777 reinterpret_cast<Address>(handle.location()));
9778 return result; 9751 return result;
9779 } 9752 }
9780 9753
9781 9754
9782 String* SharedFunctionInfo::DebugName() { 9755 String* SharedFunctionInfo::DebugName() {
9783 Object* n = name(); 9756 Object* n = name();
9784 if (!n->IsString() || String::cast(n)->length() == 0) return inferred_name(); 9757 if (!n->IsString() || String::cast(n)->length() == 0) return inferred_name();
9785 return String::cast(n); 9758 return String::cast(n);
9786 } 9759 }
9787 9760
(...skipping 6647 matching lines...) Expand 10 before | Expand all | Expand 10 after
16435 Handle<DependentCode> codes = 16408 Handle<DependentCode> codes =
16436 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), 16409 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()),
16437 DependentCode::kPropertyCellChangedGroup, 16410 DependentCode::kPropertyCellChangedGroup,
16438 info->object_wrapper()); 16411 info->object_wrapper());
16439 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); 16412 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes);
16440 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( 16413 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add(
16441 cell, info->zone()); 16414 cell, info->zone());
16442 } 16415 }
16443 16416
16444 } } // namespace v8::internal 16417 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698