Handlify all context allocators from the Heap.
R=yangguo@chromium.org BUG= Review URL: https://codereview.chromium.org/230393002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20600 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
c85cc472e7
commit
f1a22a0fd2
@ -582,10 +582,16 @@ Handle<Context> Factory::NewNativeContext() {
|
||||
|
||||
Handle<Context> Factory::NewGlobalContext(Handle<JSFunction> function,
|
||||
Handle<ScopeInfo> scope_info) {
|
||||
CALL_HEAP_FUNCTION(
|
||||
isolate(),
|
||||
isolate()->heap()->AllocateGlobalContext(*function, *scope_info),
|
||||
Context);
|
||||
Handle<FixedArray> array =
|
||||
NewFixedArray(scope_info->ContextLength(), TENURED);
|
||||
array->set_map_no_write_barrier(*global_context_map());
|
||||
Handle<Context> context = Handle<Context>::cast(array);
|
||||
context->set_closure(*function);
|
||||
context->set_previous(function->context());
|
||||
context->set_extension(*scope_info);
|
||||
context->set_global_object(function->context()->global_object());
|
||||
ASSERT(context->IsGlobalContext());
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
@ -602,10 +608,15 @@ Handle<Context> Factory::NewModuleContext(Handle<ScopeInfo> scope_info) {
|
||||
|
||||
Handle<Context> Factory::NewFunctionContext(int length,
|
||||
Handle<JSFunction> function) {
|
||||
CALL_HEAP_FUNCTION(
|
||||
isolate(),
|
||||
isolate()->heap()->AllocateFunctionContext(length, *function),
|
||||
Context);
|
||||
ASSERT(length >= Context::MIN_CONTEXT_SLOTS);
|
||||
Handle<FixedArray> array = NewFixedArray(length);
|
||||
array->set_map_no_write_barrier(*function_context_map());
|
||||
Handle<Context> context = Handle<Context>::cast(array);
|
||||
context->set_closure(*function);
|
||||
context->set_previous(function->context());
|
||||
context->set_extension(Smi::FromInt(0));
|
||||
context->set_global_object(function->context()->global_object());
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
@ -613,35 +624,45 @@ Handle<Context> Factory::NewCatchContext(Handle<JSFunction> function,
|
||||
Handle<Context> previous,
|
||||
Handle<String> name,
|
||||
Handle<Object> thrown_object) {
|
||||
CALL_HEAP_FUNCTION(
|
||||
isolate(),
|
||||
isolate()->heap()->AllocateCatchContext(*function,
|
||||
*previous,
|
||||
*name,
|
||||
*thrown_object),
|
||||
Context);
|
||||
STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == Context::THROWN_OBJECT_INDEX);
|
||||
Handle<FixedArray> array = NewFixedArray(Context::MIN_CONTEXT_SLOTS + 1);
|
||||
array->set_map_no_write_barrier(*catch_context_map());
|
||||
Handle<Context> context = Handle<Context>::cast(array);
|
||||
context->set_closure(*function);
|
||||
context->set_previous(*previous);
|
||||
context->set_extension(*name);
|
||||
context->set_global_object(previous->global_object());
|
||||
context->set(Context::THROWN_OBJECT_INDEX, *thrown_object);
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
Handle<Context> Factory::NewWithContext(Handle<JSFunction> function,
|
||||
Handle<Context> previous,
|
||||
Handle<JSObject> extension) {
|
||||
CALL_HEAP_FUNCTION(
|
||||
isolate(),
|
||||
isolate()->heap()->AllocateWithContext(*function, *previous, *extension),
|
||||
Context);
|
||||
Handle<JSReceiver> extension) {
|
||||
Handle<FixedArray> array = NewFixedArray(Context::MIN_CONTEXT_SLOTS);
|
||||
array->set_map_no_write_barrier(*with_context_map());
|
||||
Handle<Context> context = Handle<Context>::cast(array);
|
||||
context->set_closure(*function);
|
||||
context->set_previous(*previous);
|
||||
context->set_extension(*extension);
|
||||
context->set_global_object(previous->global_object());
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
Handle<Context> Factory::NewBlockContext(Handle<JSFunction> function,
|
||||
Handle<Context> previous,
|
||||
Handle<ScopeInfo> scope_info) {
|
||||
CALL_HEAP_FUNCTION(
|
||||
isolate(),
|
||||
isolate()->heap()->AllocateBlockContext(*function,
|
||||
*previous,
|
||||
*scope_info),
|
||||
Context);
|
||||
Handle<FixedArray> array =
|
||||
NewFixedArrayWithHoles(scope_info->ContextLength());
|
||||
array->set_map_no_write_barrier(*block_context_map());
|
||||
Handle<Context> context = Handle<Context>::cast(array);
|
||||
context->set_closure(*function);
|
||||
context->set_previous(*previous);
|
||||
context->set_extension(*scope_info);
|
||||
context->set_global_object(previous->global_object());
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
|
@ -200,7 +200,7 @@ class Factory V8_FINAL {
|
||||
// Create a 'with' context.
|
||||
Handle<Context> NewWithContext(Handle<JSFunction> function,
|
||||
Handle<Context> previous,
|
||||
Handle<JSObject> extension);
|
||||
Handle<JSReceiver> extension);
|
||||
|
||||
// Create a block context.
|
||||
Handle<Context> NewBlockContext(Handle<JSFunction> function,
|
||||
|
91
src/heap.cc
91
src/heap.cc
@ -5411,97 +5411,6 @@ MaybeObject* Heap::AllocatePrivateSymbol() {
|
||||
}
|
||||
|
||||
|
||||
MaybeObject* Heap::AllocateGlobalContext(JSFunction* function,
|
||||
ScopeInfo* scope_info) {
|
||||
Object* result;
|
||||
{ MaybeObject* maybe_result =
|
||||
AllocateFixedArray(scope_info->ContextLength(), TENURED);
|
||||
if (!maybe_result->ToObject(&result)) return maybe_result;
|
||||
}
|
||||
Context* context = reinterpret_cast<Context*>(result);
|
||||
context->set_map_no_write_barrier(global_context_map());
|
||||
context->set_closure(function);
|
||||
context->set_previous(function->context());
|
||||
context->set_extension(scope_info);
|
||||
context->set_global_object(function->context()->global_object());
|
||||
ASSERT(context->IsGlobalContext());
|
||||
ASSERT(result->IsContext());
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
MaybeObject* Heap::AllocateFunctionContext(int length, JSFunction* function) {
|
||||
ASSERT(length >= Context::MIN_CONTEXT_SLOTS);
|
||||
Object* result;
|
||||
{ MaybeObject* maybe_result = AllocateFixedArray(length);
|
||||
if (!maybe_result->ToObject(&result)) return maybe_result;
|
||||
}
|
||||
Context* context = reinterpret_cast<Context*>(result);
|
||||
context->set_map_no_write_barrier(function_context_map());
|
||||
context->set_closure(function);
|
||||
context->set_previous(function->context());
|
||||
context->set_extension(Smi::FromInt(0));
|
||||
context->set_global_object(function->context()->global_object());
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
MaybeObject* Heap::AllocateCatchContext(JSFunction* function,
|
||||
Context* previous,
|
||||
String* name,
|
||||
Object* thrown_object) {
|
||||
STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == Context::THROWN_OBJECT_INDEX);
|
||||
Object* result;
|
||||
{ MaybeObject* maybe_result =
|
||||
AllocateFixedArray(Context::MIN_CONTEXT_SLOTS + 1);
|
||||
if (!maybe_result->ToObject(&result)) return maybe_result;
|
||||
}
|
||||
Context* context = reinterpret_cast<Context*>(result);
|
||||
context->set_map_no_write_barrier(catch_context_map());
|
||||
context->set_closure(function);
|
||||
context->set_previous(previous);
|
||||
context->set_extension(name);
|
||||
context->set_global_object(previous->global_object());
|
||||
context->set(Context::THROWN_OBJECT_INDEX, thrown_object);
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
MaybeObject* Heap::AllocateWithContext(JSFunction* function,
|
||||
Context* previous,
|
||||
JSReceiver* extension) {
|
||||
Object* result;
|
||||
{ MaybeObject* maybe_result = AllocateFixedArray(Context::MIN_CONTEXT_SLOTS);
|
||||
if (!maybe_result->ToObject(&result)) return maybe_result;
|
||||
}
|
||||
Context* context = reinterpret_cast<Context*>(result);
|
||||
context->set_map_no_write_barrier(with_context_map());
|
||||
context->set_closure(function);
|
||||
context->set_previous(previous);
|
||||
context->set_extension(extension);
|
||||
context->set_global_object(previous->global_object());
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
MaybeObject* Heap::AllocateBlockContext(JSFunction* function,
|
||||
Context* previous,
|
||||
ScopeInfo* scope_info) {
|
||||
Object* result;
|
||||
{ MaybeObject* maybe_result =
|
||||
AllocateFixedArrayWithHoles(scope_info->ContextLength());
|
||||
if (!maybe_result->ToObject(&result)) return maybe_result;
|
||||
}
|
||||
Context* context = reinterpret_cast<Context*>(result);
|
||||
context->set_map_no_write_barrier(block_context_map());
|
||||
context->set_closure(function);
|
||||
context->set_previous(previous);
|
||||
context->set_extension(scope_info);
|
||||
context->set_global_object(previous->global_object());
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
MaybeObject* Heap::AllocateStruct(InstanceType type) {
|
||||
Map* map;
|
||||
switch (type) {
|
||||
|
23
src/heap.h
23
src/heap.h
@ -1015,29 +1015,6 @@ class Heap {
|
||||
MUST_USE_RESULT MaybeObject* AllocateHashTable(
|
||||
int length, PretenureFlag pretenure = NOT_TENURED);
|
||||
|
||||
// Allocate a global context.
|
||||
MUST_USE_RESULT MaybeObject* AllocateGlobalContext(JSFunction* function,
|
||||
ScopeInfo* scope_info);
|
||||
|
||||
// Allocate a function context.
|
||||
MUST_USE_RESULT MaybeObject* AllocateFunctionContext(int length,
|
||||
JSFunction* function);
|
||||
|
||||
// Allocate a catch context.
|
||||
MUST_USE_RESULT MaybeObject* AllocateCatchContext(JSFunction* function,
|
||||
Context* previous,
|
||||
String* name,
|
||||
Object* thrown_object);
|
||||
// Allocate a 'with' context.
|
||||
MUST_USE_RESULT MaybeObject* AllocateWithContext(JSFunction* function,
|
||||
Context* previous,
|
||||
JSReceiver* extension);
|
||||
|
||||
// Allocate a block context.
|
||||
MUST_USE_RESULT MaybeObject* AllocateBlockContext(JSFunction* function,
|
||||
Context* previous,
|
||||
ScopeInfo* info);
|
||||
|
||||
// Allocates a new utility object in the old generation.
|
||||
MUST_USE_RESULT MaybeObject* AllocateStruct(InstanceType type);
|
||||
|
||||
|
119
src/runtime.cc
119
src/runtime.cc
@ -8954,125 +8954,110 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetConstructorDelegate) {
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_NewGlobalContext) {
|
||||
SealHandleScope shs(isolate);
|
||||
HandleScope scope(isolate);
|
||||
ASSERT(args.length() == 2);
|
||||
|
||||
CONVERT_ARG_CHECKED(JSFunction, function, 0);
|
||||
CONVERT_ARG_CHECKED(ScopeInfo, scope_info, 1);
|
||||
Context* result;
|
||||
MaybeObject* maybe_result =
|
||||
isolate->heap()->AllocateGlobalContext(function, scope_info);
|
||||
if (!maybe_result->To(&result)) return maybe_result;
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1);
|
||||
Handle<Context> result =
|
||||
isolate->factory()->NewGlobalContext(function, scope_info);
|
||||
|
||||
ASSERT(function->context() == isolate->context());
|
||||
ASSERT(function->context()->global_object() == result->global_object());
|
||||
result->global_object()->set_global_context(result);
|
||||
|
||||
return result; // non-failure
|
||||
result->global_object()->set_global_context(*result);
|
||||
return *result;
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_NewFunctionContext) {
|
||||
SealHandleScope shs(isolate);
|
||||
HandleScope scope(isolate);
|
||||
ASSERT(args.length() == 1);
|
||||
|
||||
CONVERT_ARG_CHECKED(JSFunction, function, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
|
||||
int length = function->shared()->scope_info()->ContextLength();
|
||||
return isolate->heap()->AllocateFunctionContext(length, function);
|
||||
Handle<Context> context =
|
||||
isolate->factory()->NewFunctionContext(length, function);
|
||||
return *context;
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_PushWithContext) {
|
||||
SealHandleScope shs(isolate);
|
||||
HandleScope scope(isolate);
|
||||
ASSERT(args.length() == 2);
|
||||
JSReceiver* extension_object;
|
||||
Handle<JSReceiver> extension_object;
|
||||
if (args[0]->IsJSReceiver()) {
|
||||
extension_object = JSReceiver::cast(args[0]);
|
||||
extension_object = args.at<JSReceiver>(0);
|
||||
} else {
|
||||
// Convert the object to a proper JavaScript object.
|
||||
MaybeObject* maybe_js_object = args[0]->ToObject(isolate);
|
||||
if (!maybe_js_object->To(&extension_object)) {
|
||||
if (Failure::cast(maybe_js_object)->IsInternalError()) {
|
||||
HandleScope scope(isolate);
|
||||
Handle<Object> handle = args.at<Object>(0);
|
||||
Handle<Object> result =
|
||||
isolate->factory()->NewTypeError("with_expression",
|
||||
HandleVector(&handle, 1));
|
||||
return isolate->Throw(*result);
|
||||
} else {
|
||||
return maybe_js_object;
|
||||
}
|
||||
Handle<Object> object = isolate->factory()->ToObject(args.at<Object>(0));
|
||||
if (object.is_null()) {
|
||||
Handle<Object> handle = args.at<Object>(0);
|
||||
Handle<Object> result =
|
||||
isolate->factory()->NewTypeError("with_expression",
|
||||
HandleVector(&handle, 1));
|
||||
return isolate->Throw(*result);
|
||||
}
|
||||
extension_object = Handle<JSReceiver>::cast(object);
|
||||
}
|
||||
|
||||
JSFunction* function;
|
||||
Handle<JSFunction> function;
|
||||
if (args[1]->IsSmi()) {
|
||||
// A smi sentinel indicates a context nested inside global code rather
|
||||
// than some function. There is a canonical empty function that can be
|
||||
// gotten from the native context.
|
||||
function = isolate->context()->native_context()->closure();
|
||||
function = handle(isolate->context()->native_context()->closure());
|
||||
} else {
|
||||
function = JSFunction::cast(args[1]);
|
||||
function = args.at<JSFunction>(1);
|
||||
}
|
||||
|
||||
Context* context;
|
||||
MaybeObject* maybe_context =
|
||||
isolate->heap()->AllocateWithContext(function,
|
||||
isolate->context(),
|
||||
extension_object);
|
||||
if (!maybe_context->To(&context)) return maybe_context;
|
||||
isolate->set_context(context);
|
||||
return context;
|
||||
Handle<Context> current(isolate->context());
|
||||
Handle<Context> context = isolate->factory()->NewWithContext(
|
||||
function, current, extension_object);
|
||||
isolate->set_context(*context);
|
||||
return *context;
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_PushCatchContext) {
|
||||
SealHandleScope shs(isolate);
|
||||
HandleScope scope(isolate);
|
||||
ASSERT(args.length() == 3);
|
||||
String* name = String::cast(args[0]);
|
||||
Object* thrown_object = args[1];
|
||||
JSFunction* function;
|
||||
CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(Object, thrown_object, 1);
|
||||
Handle<JSFunction> function;
|
||||
if (args[2]->IsSmi()) {
|
||||
// A smi sentinel indicates a context nested inside global code rather
|
||||
// than some function. There is a canonical empty function that can be
|
||||
// gotten from the native context.
|
||||
function = isolate->context()->native_context()->closure();
|
||||
function = handle(isolate->context()->native_context()->closure());
|
||||
} else {
|
||||
function = JSFunction::cast(args[2]);
|
||||
function = args.at<JSFunction>(2);
|
||||
}
|
||||
Context* context;
|
||||
MaybeObject* maybe_context =
|
||||
isolate->heap()->AllocateCatchContext(function,
|
||||
isolate->context(),
|
||||
name,
|
||||
thrown_object);
|
||||
if (!maybe_context->To(&context)) return maybe_context;
|
||||
isolate->set_context(context);
|
||||
return context;
|
||||
Handle<Context> current(isolate->context());
|
||||
Handle<Context> context = isolate->factory()->NewCatchContext(
|
||||
function, current, name, thrown_object);
|
||||
isolate->set_context(*context);
|
||||
return *context;
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_PushBlockContext) {
|
||||
SealHandleScope shs(isolate);
|
||||
HandleScope scope(isolate);
|
||||
ASSERT(args.length() == 2);
|
||||
ScopeInfo* scope_info = ScopeInfo::cast(args[0]);
|
||||
JSFunction* function;
|
||||
CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 0);
|
||||
Handle<JSFunction> function;
|
||||
if (args[1]->IsSmi()) {
|
||||
// A smi sentinel indicates a context nested inside global code rather
|
||||
// than some function. There is a canonical empty function that can be
|
||||
// gotten from the native context.
|
||||
function = isolate->context()->native_context()->closure();
|
||||
function = handle(isolate->context()->native_context()->closure());
|
||||
} else {
|
||||
function = JSFunction::cast(args[1]);
|
||||
function = args.at<JSFunction>(1);
|
||||
}
|
||||
Context* context;
|
||||
MaybeObject* maybe_context =
|
||||
isolate->heap()->AllocateBlockContext(function,
|
||||
isolate->context(),
|
||||
scope_info);
|
||||
if (!maybe_context->To(&context)) return maybe_context;
|
||||
isolate->set_context(context);
|
||||
return context;
|
||||
Handle<Context> current(isolate->context());
|
||||
Handle<Context> context = isolate->factory()->NewBlockContext(
|
||||
function, current, scope_info);
|
||||
isolate->set_context(*context);
|
||||
return *context;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user