Revision: 6993
Author: [email protected]
Date: Tue Mar 1 06:00:55 2011
Log: Remove HandleCell and use GlobalHandle and HandleScope::Escape instead.
Added HandleScope::Escape to HandleScope to allow exiting a value
from a scope.
Review URL: http://codereview.chromium.org/6594075
http://code.google.com/p/v8/source/detail?r=6993
Modified:
/branches/bleeding_edge/src/handles-inl.h
/branches/bleeding_edge/src/handles.h
/branches/bleeding_edge/src/runtime.cc
=======================================
--- /branches/bleeding_edge/src/handles-inl.h Thu Feb 24 06:00:52 2011
+++ /branches/bleeding_edge/src/handles-inl.h Tue Mar 1 06:00:55 2011
@@ -49,16 +49,6 @@
ASSERT(reinterpret_cast<Address>(*location_) != kHandleZapValue);
return *BitCast<T**>(location_);
}
-
-
-template <typename T>
-HandleCell<T>::HandleCell(T* value)
- : location_(HandleScope::CreateHandle(value)) { }
-
-
-template <typename T>
-HandleCell<T>::HandleCell(Handle<T> value)
- : location_(HandleScope::CreateHandle(*value)) { }
#ifdef DEBUG
=======================================
--- /branches/bleeding_edge/src/handles.h Mon Feb 28 22:10:41 2011
+++ /branches/bleeding_edge/src/handles.h Tue Mar 1 06:00:55 2011
@@ -93,55 +93,6 @@
};
-// A handle-scope based variable. The value stored in the variable can
change
-// over time. The value stored in the variable at any time is a root
-// for garbage collection.
-// The variable is backed by the current HandleScope.
-template <typename T>
-class HandleCell {
- public:
- // Create a new HandleCell holding the given value.
- explicit HandleCell(Handle<T> value);
- explicit HandleCell(T* value);
-
- // Create an alias of an existing HandleCell.
- explicit HandleCell(const HandleCell<T>& value)
- : location_(value.location_) { }
-
- INLINE(T* operator->() const) { return operator*(); }
- INLINE(T* operator*() const) {
- return *location_;
- }
- INLINE(void operator=(T* value)) {
- *location_ = value;
- }
- INLINE(void operator=(Handle<T> value)) {
- *location_ = *value;
- }
- INLINE(void operator=(const HandleCell<T>& value)) {
- *location_ = *value.location_;
- }
-
- // Extract the value of the variable and cast it to a give type.
- // This is typically used for calling methods on a more specialized type.
- template <typename S>
- inline S* cast() {
- S::cast(*location_);
- return *reinterpret_cast<S**>(location_);
- }
-
- Handle<T> ToHandle() const {
- return Handle<T>(*location_);
- }
-
- private:
- // Prevent implicit constructor from being created.
- HandleCell();
-
- T** location_;
-};
-
-
// A stack-allocated class that governs a number of local handles.
// After a handle scope has been created, all local handles will be
// allocated within that handle scope until either the handle scope is
@@ -161,15 +112,7 @@
}
~HandleScope() {
- current_.next = prev_next_;
- current_.level--;
- if (current_.limit != prev_limit_) {
- current_.limit = prev_limit_;
- DeleteExtensions();
- }
-#ifdef DEBUG
- ZapRange(prev_next_, prev_limit_);
-#endif
+ CloseScope();
}
// Counts the number of allocated handles.
@@ -196,6 +139,26 @@
static Address current_next_address();
static Address current_limit_address();
static Address current_level_address();
+
+ // Closes the HandleScope (invalidating all handles
+ // created in the scope of the HandleScope) and returns
+ // a Handle backed by the parent scope holding the
+ // value of the argument handle.
+ template <typename T>
+ Handle<T> CloseAndEscape(Handle<T> handle_value) {
+ T* value = *handle_value;
+ // Throw away all handles in the current scope.
+ CloseScope();
+ // Allocate one handle in the parent scope.
+ ASSERT(current_.level > 0);
+ Handle<T> result(CreateHandle<T>(value));
+ // Reinitialize the current scope (so that it's ready
+ // to be used or closed again).
+ prev_next_ = current_.next;
+ prev_limit_ = current_.limit;
+ current_.level++;
+ return result;
+ }
private:
// Prevent heap allocation or illegal handle scopes.
@@ -204,9 +167,23 @@
void* operator new(size_t size);
void operator delete(void* size_t);
+ inline void CloseScope() {
+ current_.next = prev_next_;
+ current_.level--;
+ if (current_.limit != prev_limit_) {
+ current_.limit = prev_limit_;
+ DeleteExtensions();
+ }
+#ifdef DEBUG
+ ZapRange(prev_next_, prev_limit_);
+#endif
+ }
+
static v8::ImplementationUtilities::HandleScopeData current_;
- Object** const prev_next_;
- Object** const prev_limit_;
+ // Holds values on entry. The prev_next_ value is never NULL
+ // on_entry, but is set to NULL when this scope is closed.
+ Object** prev_next_;
+ Object** prev_limit_;
// Extend the handle scope making room for more handles.
static internal::Object** Extend();
=======================================
--- /branches/bleeding_edge/src/runtime.cc Tue Mar 1 05:16:57 2011
+++ /branches/bleeding_edge/src/runtime.cc Tue Mar 1 06:00:55 2011
@@ -40,6 +40,7 @@
#include "debug.h"
#include "deoptimizer.h"
#include "execution.h"
+#include "global-handles.h"
#include "jsregexp.h"
#include "liveedit.h"
#include "parser.h"
@@ -8041,9 +8042,13 @@
public:
ArrayConcatVisitor(Handle<FixedArray> storage,
bool fast_elements) :
- storage_(storage),
+ storage_(Handle<FixedArray>::cast(GlobalHandles::Create(*storage))),
index_offset_(0u),
fast_elements_(fast_elements) { }
+
+ ~ArrayConcatVisitor() {
+ clear_storage();
+ }
void visit(uint32_t i, Handle<Object> elm) {
if (i >= JSObject::kMaxElementCount - index_offset_) return;
@@ -8062,11 +8067,13 @@
// Fall-through to dictionary mode.
}
ASSERT(!fast_elements_);
- Handle<NumberDictionary> dict(storage_.cast<NumberDictionary>());
+ Handle<NumberDictionary> dict(NumberDictionary::cast(*storage_));
Handle<NumberDictionary> result =
Factory::DictionaryAtNumberPut(dict, index, elm);
if (!result.is_identical_to(dict)) {
- storage_ = Handle<FixedArray>::cast(result);
+ // Dictionary needed to grow.
+ clear_storage();
+ set_storage(*result);
}
}
@@ -8098,23 +8105,35 @@
// Convert storage to dictionary mode.
void SetDictionaryMode(uint32_t index) {
ASSERT(fast_elements_);
- Handle<FixedArray> current_storage(storage_.ToHandle());
- HandleCell<NumberDictionary> slow_storage(
+ Handle<FixedArray> current_storage(*storage_);
+ Handle<NumberDictionary> slow_storage(
Factory::NewNumberDictionary(current_storage->length()));
uint32_t current_length =
static_cast<uint32_t>(current_storage->length());
for (uint32_t i = 0; i < current_length; i++) {
HandleScope loop_scope;
Handle<Object> element(current_storage->get(i));
if (!element->IsTheHole()) {
- slow_storage =
- Factory::DictionaryAtNumberPut(slow_storage.ToHandle(), i,
element);
+ Handle<NumberDictionary> new_storage =
+ Factory::DictionaryAtNumberPut(slow_storage, i, element);
+ if (!new_storage.is_identical_to(slow_storage)) {
+ slow_storage = loop_scope.CloseAndEscape(new_storage);
+ }
}
}
- storage_ = slow_storage.cast<FixedArray>();
+ clear_storage();
+ set_storage(*slow_storage);
fast_elements_ = false;
}
- HandleCell<FixedArray> storage_;
+ inline void clear_storage() {
+ GlobalHandles::Destroy(Handle<Object>::cast(storage_).location());
+ }
+
+ inline void set_storage(FixedArray* storage) {
+ storage_ = Handle<FixedArray>::cast(GlobalHandles::Create(storage));
+ }
+
+ Handle<FixedArray> storage_; // Always a global handle.
// Index after last seen index. Always less than or equal to
// JSObject::kMaxElementCount.
uint32_t index_offset_;
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev