Handlify six more allocators in from the Heap class.

R=yangguo@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20808 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
mstarzinger@chromium.org 2014-04-16 13:35:36 +00:00
parent 7af5597287
commit e8ad0c3e53
4 changed files with 113 additions and 228 deletions

View File

@ -559,19 +559,45 @@ Handle<String> Factory::NewProperSubString(Handle<String> str,
MaybeHandle<String> Factory::NewExternalStringFromAscii(
const ExternalAsciiString::Resource* resource) {
CALL_HEAP_FUNCTION(
isolate(),
isolate()->heap()->AllocateExternalStringFromAscii(resource),
String);
size_t length = resource->length();
if (length > static_cast<size_t>(String::kMaxLength)) {
isolate()->ThrowInvalidStringLength();
return MaybeHandle<String>();
}
Handle<Map> map = external_ascii_string_map();
Handle<ExternalAsciiString> external_string =
New<ExternalAsciiString>(map, NEW_SPACE);
external_string->set_length(static_cast<int>(length));
external_string->set_hash_field(String::kEmptyHashField);
external_string->set_resource(resource);
return external_string;
}
MaybeHandle<String> Factory::NewExternalStringFromTwoByte(
const ExternalTwoByteString::Resource* resource) {
CALL_HEAP_FUNCTION(
isolate(),
isolate()->heap()->AllocateExternalStringFromTwoByte(resource),
String);
size_t length = resource->length();
if (length > static_cast<size_t>(String::kMaxLength)) {
isolate()->ThrowInvalidStringLength();
return MaybeHandle<String>();
}
// For small strings we check whether the resource contains only
// one byte characters. If yes, we use a different string map.
static const size_t kOneByteCheckLengthLimit = 32;
bool is_one_byte = length <= kOneByteCheckLengthLimit &&
String::IsOneByte(resource->data(), static_cast<int>(length));
Handle<Map> map = is_one_byte ?
external_string_with_one_byte_data_map() : external_string_map();
Handle<ExternalTwoByteString> external_string =
New<ExternalTwoByteString>(map, NEW_SPACE);
external_string->set_length(static_cast<int>(length));
external_string->set_hash_field(String::kEmptyHashField);
external_string->set_resource(resource);
return external_string;
}
@ -1614,10 +1640,18 @@ Handle<JSTypedArray> Factory::NewJSTypedArray(ExternalArrayType type) {
Handle<JSProxy> Factory::NewJSProxy(Handle<Object> handler,
Handle<Object> prototype) {
CALL_HEAP_FUNCTION(
isolate(),
isolate()->heap()->AllocateJSProxy(*handler, *prototype),
JSProxy);
// Allocate map.
// TODO(rossberg): Once we optimize proxies, think about a scheme to share
// maps. Will probably depend on the identity of the handler object, too.
Handle<Map> map = NewMap(JS_PROXY_TYPE, JSProxy::kSize);
map->set_prototype(*prototype);
// Allocate the proxy object.
Handle<JSProxy> result = New<JSProxy>(map, NEW_SPACE);
result->InitializeBody(map->instance_size(), Smi::FromInt(0));
result->set_handler(*handler);
result->set_hash(*undefined_value(), SKIP_WRITE_BARRIER);
return result;
}
@ -1625,11 +1659,20 @@ Handle<JSProxy> Factory::NewJSFunctionProxy(Handle<Object> handler,
Handle<Object> call_trap,
Handle<Object> construct_trap,
Handle<Object> prototype) {
CALL_HEAP_FUNCTION(
isolate(),
isolate()->heap()->AllocateJSFunctionProxy(
*handler, *call_trap, *construct_trap, *prototype),
JSProxy);
// Allocate map.
// TODO(rossberg): Once we optimize proxies, think about a scheme to share
// maps. Will probably depend on the identity of the handler object, too.
Handle<Map> map = NewMap(JS_FUNCTION_PROXY_TYPE, JSFunctionProxy::kSize);
map->set_prototype(*prototype);
// Allocate the proxy object.
Handle<JSFunctionProxy> result = New<JSFunctionProxy>(map, NEW_SPACE);
result->InitializeBody(map->instance_size(), Smi::FromInt(0));
result->set_handler(*handler);
result->set_hash(*undefined_value(), SKIP_WRITE_BARRIER);
result->set_call_trap(*call_trap);
result->set_construct_trap(*construct_trap);
return result;
}
@ -1757,21 +1800,57 @@ Handle<JSMessageObject> Factory::NewJSMessageObject(
int end_position,
Handle<Object> script,
Handle<Object> stack_frames) {
CALL_HEAP_FUNCTION(isolate(),
isolate()->heap()->AllocateJSMessageObject(*type,
*arguments,
start_position,
end_position,
*script,
*stack_frames),
JSMessageObject);
Handle<Map> map = message_object_map();
Handle<JSMessageObject> message = New<JSMessageObject>(map, NEW_SPACE);
message->set_properties(*empty_fixed_array(), SKIP_WRITE_BARRIER);
message->initialize_elements();
message->set_elements(*empty_fixed_array(), SKIP_WRITE_BARRIER);
message->set_type(*type);
message->set_arguments(*arguments);
message->set_start_position(start_position);
message->set_end_position(end_position);
message->set_script(*script);
message->set_stack_frames(*stack_frames);
return message;
}
Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(Handle<String> name) {
CALL_HEAP_FUNCTION(isolate(),
isolate()->heap()->AllocateSharedFunctionInfo(*name),
SharedFunctionInfo);
Handle<Map> map = shared_function_info_map();
Handle<SharedFunctionInfo> share = New<SharedFunctionInfo>(map,
OLD_POINTER_SPACE);
// Set pointer fields.
share->set_name(*name);
Code* illegal = isolate()->builtins()->builtin(Builtins::kIllegal);
share->set_code(illegal);
share->set_optimized_code_map(Smi::FromInt(0));
share->set_scope_info(ScopeInfo::Empty(isolate()));
Code* construct_stub =
isolate()->builtins()->builtin(Builtins::kJSConstructStubGeneric);
share->set_construct_stub(construct_stub);
share->set_instance_class_name(*Object_string());
share->set_function_data(*undefined_value(), SKIP_WRITE_BARRIER);
share->set_script(*undefined_value(), SKIP_WRITE_BARRIER);
share->set_debug_info(*undefined_value(), SKIP_WRITE_BARRIER);
share->set_inferred_name(*empty_string(), SKIP_WRITE_BARRIER);
share->set_initial_map(*undefined_value(), SKIP_WRITE_BARRIER);
share->set_ast_node_count(0);
share->set_counters(0);
// Set integer fields (smi or int, depending on the architecture).
share->set_length(0);
share->set_formal_parameter_count(0);
share->set_expected_nof_properties(0);
share->set_num_literals(0);
share->set_start_position_and_type(0);
share->set_end_position(0);
share->set_function_token_position(0);
// All compiler hints default to false or 0.
share->set_compiler_hints(0);
share->set_opt_count_and_bailout_reason(0);
return share;
}

View File

@ -171,7 +171,8 @@ class Factory V8_FINAL {
// Creates a new external String object. There are two String encodings
// in the system: ASCII and two byte. Unlike other String types, it does
// not make sense to have a UTF-8 factory function for external strings,
// because we cannot change the underlying buffer.
// because we cannot change the underlying buffer. Note that these strings
// are backed by a string resource that resides outside the V8 heap.
MUST_USE_RESULT MaybeHandle<String> NewExternalStringFromAscii(
const ExternalAsciiString::Resource* resource);
MUST_USE_RESULT MaybeHandle<String> NewExternalStringFromTwoByte(
@ -386,8 +387,10 @@ class Factory V8_FINAL {
Handle<JSDataView> NewJSDataView();
// Allocates a Harmony proxy.
Handle<JSProxy> NewJSProxy(Handle<Object> handler, Handle<Object> prototype);
// Allocates a Harmony function proxy.
Handle<JSProxy> NewJSFunctionProxy(Handle<Object> handler,
Handle<Object> call_trap,
Handle<Object> construct_trap,
@ -545,6 +548,7 @@ class Factory V8_FINAL {
return Handle<String>(&isolate()->heap()->hidden_string_);
}
// Allocates a new SharedFunctionInfo object.
Handle<SharedFunctionInfo> NewSharedFunctionInfo(
Handle<String> name,
int number_of_literals,
@ -553,6 +557,7 @@ class Factory V8_FINAL {
Handle<ScopeInfo> scope_info);
Handle<SharedFunctionInfo> NewSharedFunctionInfo(Handle<String> name);
// Allocates a new JSMessageObject object.
Handle<JSMessageObject> NewJSMessageObject(
Handle<String> type,
Handle<JSArray> arguments,

View File

@ -3543,119 +3543,6 @@ MaybeObject* Heap::AllocateForeign(Address address, PretenureFlag pretenure) {
}
MaybeObject* Heap::AllocateSharedFunctionInfo(Object* name) {
SharedFunctionInfo* share;
MaybeObject* maybe = Allocate(shared_function_info_map(), OLD_POINTER_SPACE);
if (!maybe->To<SharedFunctionInfo>(&share)) return maybe;
// Set pointer fields.
share->set_name(name);
Code* illegal = isolate_->builtins()->builtin(Builtins::kIllegal);
share->set_code(illegal);
share->set_optimized_code_map(Smi::FromInt(0));
share->set_scope_info(ScopeInfo::Empty(isolate_));
Code* construct_stub =
isolate_->builtins()->builtin(Builtins::kJSConstructStubGeneric);
share->set_construct_stub(construct_stub);
share->set_instance_class_name(Object_string());
share->set_function_data(undefined_value(), SKIP_WRITE_BARRIER);
share->set_script(undefined_value(), SKIP_WRITE_BARRIER);
share->set_debug_info(undefined_value(), SKIP_WRITE_BARRIER);
share->set_inferred_name(empty_string(), SKIP_WRITE_BARRIER);
share->set_initial_map(undefined_value(), SKIP_WRITE_BARRIER);
share->set_ast_node_count(0);
share->set_counters(0);
// Set integer fields (smi or int, depending on the architecture).
share->set_length(0);
share->set_formal_parameter_count(0);
share->set_expected_nof_properties(0);
share->set_num_literals(0);
share->set_start_position_and_type(0);
share->set_end_position(0);
share->set_function_token_position(0);
// All compiler hints default to false or 0.
share->set_compiler_hints(0);
share->set_opt_count_and_bailout_reason(0);
return share;
}
MaybeObject* Heap::AllocateJSMessageObject(String* type,
JSArray* arguments,
int start_position,
int end_position,
Object* script,
Object* stack_frames) {
Object* result;
{ MaybeObject* maybe_result = Allocate(message_object_map(), NEW_SPACE);
if (!maybe_result->ToObject(&result)) return maybe_result;
}
JSMessageObject* message = JSMessageObject::cast(result);
message->set_properties(Heap::empty_fixed_array(), SKIP_WRITE_BARRIER);
message->initialize_elements();
message->set_elements(Heap::empty_fixed_array(), SKIP_WRITE_BARRIER);
message->set_type(type);
message->set_arguments(arguments);
message->set_start_position(start_position);
message->set_end_position(end_position);
message->set_script(script);
message->set_stack_frames(stack_frames);
return result;
}
MaybeObject* Heap::AllocateExternalStringFromAscii(
const ExternalAsciiString::Resource* resource) {
size_t length = resource->length();
if (length > static_cast<size_t>(String::kMaxLength)) {
return isolate()->ThrowInvalidStringLength();
}
Map* map = external_ascii_string_map();
Object* result;
{ MaybeObject* maybe_result = Allocate(map, NEW_SPACE);
if (!maybe_result->ToObject(&result)) return maybe_result;
}
ExternalAsciiString* external_string = ExternalAsciiString::cast(result);
external_string->set_length(static_cast<int>(length));
external_string->set_hash_field(String::kEmptyHashField);
external_string->set_resource(resource);
return result;
}
MaybeObject* Heap::AllocateExternalStringFromTwoByte(
const ExternalTwoByteString::Resource* resource) {
size_t length = resource->length();
if (length > static_cast<size_t>(String::kMaxLength)) {
return isolate()->ThrowInvalidStringLength();
}
// For small strings we check whether the resource contains only
// one byte characters. If yes, we use a different string map.
static const size_t kOneByteCheckLengthLimit = 32;
bool is_one_byte = length <= kOneByteCheckLengthLimit &&
String::IsOneByte(resource->data(), static_cast<int>(length));
Map* map = is_one_byte ?
external_string_with_one_byte_data_map() : external_string_map();
Object* result;
{ MaybeObject* maybe_result = Allocate(map, NEW_SPACE);
if (!maybe_result->ToObject(&result)) return maybe_result;
}
ExternalTwoByteString* external_string = ExternalTwoByteString::cast(result);
external_string->set_length(static_cast<int>(length));
external_string->set_hash_field(String::kEmptyHashField);
external_string->set_resource(resource);
return result;
}
MaybeObject* Heap::LookupSingleCharacterStringFromCode(uint16_t code) {
if (code <= String::kMaxOneByteCharCode) {
Object* value = single_character_string_cache()->get(code);
@ -4147,52 +4034,6 @@ MaybeObject* Heap::AllocateJSObject(JSFunction* constructor,
}
MaybeObject* Heap::AllocateJSProxy(Object* handler, Object* prototype) {
// Allocate map.
// TODO(rossberg): Once we optimize proxies, think about a scheme to share
// maps. Will probably depend on the identity of the handler object, too.
Map* map;
MaybeObject* maybe_map_obj = AllocateMap(JS_PROXY_TYPE, JSProxy::kSize);
if (!maybe_map_obj->To<Map>(&map)) return maybe_map_obj;
map->set_prototype(prototype);
// Allocate the proxy object.
JSProxy* result;
MaybeObject* maybe_result = Allocate(map, NEW_SPACE);
if (!maybe_result->To<JSProxy>(&result)) return maybe_result;
result->InitializeBody(map->instance_size(), Smi::FromInt(0));
result->set_handler(handler);
result->set_hash(undefined_value(), SKIP_WRITE_BARRIER);
return result;
}
MaybeObject* Heap::AllocateJSFunctionProxy(Object* handler,
Object* call_trap,
Object* construct_trap,
Object* prototype) {
// Allocate map.
// TODO(rossberg): Once we optimize proxies, think about a scheme to share
// maps. Will probably depend on the identity of the handler object, too.
Map* map;
MaybeObject* maybe_map_obj =
AllocateMap(JS_FUNCTION_PROXY_TYPE, JSFunctionProxy::kSize);
if (!maybe_map_obj->To<Map>(&map)) return maybe_map_obj;
map->set_prototype(prototype);
// Allocate the proxy object.
JSFunctionProxy* result;
MaybeObject* maybe_result = Allocate(map, NEW_SPACE);
if (!maybe_result->To<JSFunctionProxy>(&result)) return maybe_result;
result->InitializeBody(map->instance_size(), Smi::FromInt(0));
result->set_handler(handler);
result->set_hash(undefined_value(), SKIP_WRITE_BARRIER);
result->set_call_trap(call_trap);
result->set_construct_trap(construct_trap);
return result;
}
MaybeObject* Heap::CopyJSObject(JSObject* source, AllocationSite* site) {
// Never used to copy functions. If functions need to be copied we
// have to be careful to clear the literals array.

View File

@ -723,18 +723,6 @@ class Heap {
MUST_USE_RESULT MaybeObject* CopyJSObject(JSObject* source,
AllocationSite* site = NULL);
// Allocates a Harmony proxy or function proxy.
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
// failed.
// Please note this does not perform a garbage collection.
MUST_USE_RESULT MaybeObject* AllocateJSProxy(Object* handler,
Object* prototype);
MUST_USE_RESULT MaybeObject* AllocateJSFunctionProxy(Object* handler,
Object* call_trap,
Object* construct_trap,
Object* prototype);
// Allocates and initializes a new JavaScript object based on a map.
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
// failed.
@ -1024,34 +1012,6 @@ class Heap {
MUST_USE_RESULT MaybeObject* AllocateForeign(
Address address, PretenureFlag pretenure = NOT_TENURED);
// Allocates a new SharedFunctionInfo object.
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
// failed.
// Please note this does not perform a garbage collection.
MUST_USE_RESULT MaybeObject* AllocateSharedFunctionInfo(Object* name);
// Allocates a new JSMessageObject object.
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
// failed.
// Please note that this does not perform a garbage collection.
MUST_USE_RESULT MaybeObject* AllocateJSMessageObject(
String* type,
JSArray* arguments,
int start_position,
int end_position,
Object* script,
Object* stack_frames);
// Allocate a new external string object, which is backed by a string
// resource that resides outside the V8 heap.
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
// failed.
// Please note this does not perform a garbage collection.
MUST_USE_RESULT MaybeObject* AllocateExternalStringFromAscii(
const ExternalAsciiString::Resource* resource);
MUST_USE_RESULT MaybeObject* AllocateExternalStringFromTwoByte(
const ExternalTwoByteString::Resource* resource);
// Finalizes an external string by deleting the associated external
// data and clearing the resource pointer.
inline void FinalizeExternalString(String* string);