Commit 6475f8d7 authored by lrn@chromium.org's avatar lrn@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6993 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 97aecae1
...@@ -51,16 +51,6 @@ inline T* Handle<T>::operator*() const { ...@@ -51,16 +51,6 @@ inline T* Handle<T>::operator*() const {
} }
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 #ifdef DEBUG
inline NoHandleAllocation::NoHandleAllocation() { inline NoHandleAllocation::NoHandleAllocation() {
v8::ImplementationUtilities::HandleScopeData* current = v8::ImplementationUtilities::HandleScopeData* current =
......
...@@ -93,55 +93,6 @@ class Handle { ...@@ -93,55 +93,6 @@ class Handle {
}; };
// 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. // A stack-allocated class that governs a number of local handles.
// After a handle scope has been created, all local handles will be // After a handle scope has been created, all local handles will be
// allocated within that handle scope until either the handle scope is // allocated within that handle scope until either the handle scope is
...@@ -161,15 +112,7 @@ class HandleScope { ...@@ -161,15 +112,7 @@ class HandleScope {
} }
~HandleScope() { ~HandleScope() {
current_.next = prev_next_; CloseScope();
current_.level--;
if (current_.limit != prev_limit_) {
current_.limit = prev_limit_;
DeleteExtensions();
}
#ifdef DEBUG
ZapRange(prev_next_, prev_limit_);
#endif
} }
// Counts the number of allocated handles. // Counts the number of allocated handles.
...@@ -197,6 +140,26 @@ class HandleScope { ...@@ -197,6 +140,26 @@ class HandleScope {
static Address current_limit_address(); static Address current_limit_address();
static Address current_level_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: private:
// Prevent heap allocation or illegal handle scopes. // Prevent heap allocation or illegal handle scopes.
HandleScope(const HandleScope&); HandleScope(const HandleScope&);
...@@ -204,9 +167,23 @@ class HandleScope { ...@@ -204,9 +167,23 @@ class HandleScope {
void* operator new(size_t size); void* operator new(size_t size);
void operator delete(void* size_t); 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_; static v8::ImplementationUtilities::HandleScopeData current_;
Object** const prev_next_; // Holds values on entry. The prev_next_ value is never NULL
Object** const prev_limit_; // 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. // Extend the handle scope making room for more handles.
static internal::Object** Extend(); static internal::Object** Extend();
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include "debug.h" #include "debug.h"
#include "deoptimizer.h" #include "deoptimizer.h"
#include "execution.h" #include "execution.h"
#include "global-handles.h"
#include "jsregexp.h" #include "jsregexp.h"
#include "liveedit.h" #include "liveedit.h"
#include "parser.h" #include "parser.h"
...@@ -8041,10 +8042,14 @@ class ArrayConcatVisitor { ...@@ -8041,10 +8042,14 @@ class ArrayConcatVisitor {
public: public:
ArrayConcatVisitor(Handle<FixedArray> storage, ArrayConcatVisitor(Handle<FixedArray> storage,
bool fast_elements) : bool fast_elements) :
storage_(storage), storage_(Handle<FixedArray>::cast(GlobalHandles::Create(*storage))),
index_offset_(0u), index_offset_(0u),
fast_elements_(fast_elements) { } fast_elements_(fast_elements) { }
~ArrayConcatVisitor() {
clear_storage();
}
void visit(uint32_t i, Handle<Object> elm) { void visit(uint32_t i, Handle<Object> elm) {
if (i >= JSObject::kMaxElementCount - index_offset_) return; if (i >= JSObject::kMaxElementCount - index_offset_) return;
uint32_t index = index_offset_ + i; uint32_t index = index_offset_ + i;
...@@ -8062,11 +8067,13 @@ class ArrayConcatVisitor { ...@@ -8062,11 +8067,13 @@ class ArrayConcatVisitor {
// Fall-through to dictionary mode. // Fall-through to dictionary mode.
} }
ASSERT(!fast_elements_); ASSERT(!fast_elements_);
Handle<NumberDictionary> dict(storage_.cast<NumberDictionary>()); Handle<NumberDictionary> dict(NumberDictionary::cast(*storage_));
Handle<NumberDictionary> result = Handle<NumberDictionary> result =
Factory::DictionaryAtNumberPut(dict, index, elm); Factory::DictionaryAtNumberPut(dict, index, elm);
if (!result.is_identical_to(dict)) { if (!result.is_identical_to(dict)) {
storage_ = Handle<FixedArray>::cast(result); // Dictionary needed to grow.
clear_storage();
set_storage(*result);
} }
} }
...@@ -8098,23 +8105,35 @@ class ArrayConcatVisitor { ...@@ -8098,23 +8105,35 @@ class ArrayConcatVisitor {
// Convert storage to dictionary mode. // Convert storage to dictionary mode.
void SetDictionaryMode(uint32_t index) { void SetDictionaryMode(uint32_t index) {
ASSERT(fast_elements_); ASSERT(fast_elements_);
Handle<FixedArray> current_storage(storage_.ToHandle()); Handle<FixedArray> current_storage(*storage_);
HandleCell<NumberDictionary> slow_storage( Handle<NumberDictionary> slow_storage(
Factory::NewNumberDictionary(current_storage->length())); Factory::NewNumberDictionary(current_storage->length()));
uint32_t current_length = static_cast<uint32_t>(current_storage->length()); uint32_t current_length = static_cast<uint32_t>(current_storage->length());
for (uint32_t i = 0; i < current_length; i++) { for (uint32_t i = 0; i < current_length; i++) {
HandleScope loop_scope; HandleScope loop_scope;
Handle<Object> element(current_storage->get(i)); Handle<Object> element(current_storage->get(i));
if (!element->IsTheHole()) { if (!element->IsTheHole()) {
slow_storage = Handle<NumberDictionary> new_storage =
Factory::DictionaryAtNumberPut(slow_storage.ToHandle(), i, element); 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; 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 // Index after last seen index. Always less than or equal to
// JSObject::kMaxElementCount. // JSObject::kMaxElementCount.
uint32_t index_offset_; uint32_t index_offset_;
......
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