Select function map based on prototype and shared function info.
BUG= R=ishell@chromium.org Review URL: https://codereview.chromium.org/237963024 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20840 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
59b3dc5812
commit
107a359080
122
src/factory.cc
122
src/factory.cc
@ -975,35 +975,21 @@ Handle<ConstantPoolArray> Factory::CopyConstantPoolArray(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Handle<Map> MapForNewFunction(Isolate *isolate,
|
|
||||||
Handle<SharedFunctionInfo> function_info) {
|
|
||||||
Context *context = isolate->context()->native_context();
|
|
||||||
int map_index = Context::FunctionMapIndex(function_info->strict_mode(),
|
|
||||||
function_info->is_generator());
|
|
||||||
return Handle<Map>(Map::cast(context->get(map_index)));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
|
Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
|
||||||
Handle<SharedFunctionInfo> function_info,
|
Handle<SharedFunctionInfo> info,
|
||||||
Handle<Context> context,
|
Handle<Context> context,
|
||||||
PretenureFlag pretenure) {
|
PretenureFlag pretenure) {
|
||||||
Handle<JSFunction> result = NewFunctionHelper(
|
Handle<JSFunction> result = NewFunction(
|
||||||
MapForNewFunction(isolate(), function_info),
|
info, context, the_hole_value(), pretenure);
|
||||||
function_info,
|
|
||||||
the_hole_value(),
|
|
||||||
pretenure);
|
|
||||||
|
|
||||||
if (function_info->ic_age() != isolate()->heap()->global_ic_age()) {
|
if (info->ic_age() != isolate()->heap()->global_ic_age()) {
|
||||||
function_info->ResetForNewContext(isolate()->heap()->global_ic_age());
|
info->ResetForNewContext(isolate()->heap()->global_ic_age());
|
||||||
}
|
}
|
||||||
|
|
||||||
result->set_context(*context);
|
int index = info->SearchOptimizedCodeMap(context->native_context(),
|
||||||
|
|
||||||
int index = function_info->SearchOptimizedCodeMap(context->native_context(),
|
|
||||||
BailoutId::None());
|
BailoutId::None());
|
||||||
if (!function_info->bound() && index < 0) {
|
if (!info->bound() && index < 0) {
|
||||||
int number_of_literals = function_info->num_literals();
|
int number_of_literals = info->num_literals();
|
||||||
Handle<FixedArray> literals = NewFixedArray(number_of_literals, pretenure);
|
Handle<FixedArray> literals = NewFixedArray(number_of_literals, pretenure);
|
||||||
if (number_of_literals > 0) {
|
if (number_of_literals > 0) {
|
||||||
// Store the native context in the literals array prefix. This
|
// Store the native context in the literals array prefix. This
|
||||||
@ -1017,10 +1003,9 @@ Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
|
|||||||
|
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
// Caching of optimized code enabled and optimized code found.
|
// Caching of optimized code enabled and optimized code found.
|
||||||
FixedArray* literals =
|
FixedArray* literals = info->GetLiteralsFromOptimizedCodeMap(index);
|
||||||
function_info->GetLiteralsFromOptimizedCodeMap(index);
|
|
||||||
if (literals != NULL) result->set_literals(literals);
|
if (literals != NULL) result->set_literals(literals);
|
||||||
Code* code = function_info->GetCodeFromOptimizedCodeMap(index);
|
Code* code = info->GetCodeFromOptimizedCodeMap(index);
|
||||||
ASSERT(!code->marked_for_deoptimization());
|
ASSERT(!code->marked_for_deoptimization());
|
||||||
result->ReplaceCode(code);
|
result->ReplaceCode(code);
|
||||||
return result;
|
return result;
|
||||||
@ -1029,9 +1014,9 @@ Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
|
|||||||
if (isolate()->use_crankshaft() &&
|
if (isolate()->use_crankshaft() &&
|
||||||
FLAG_always_opt &&
|
FLAG_always_opt &&
|
||||||
result->is_compiled() &&
|
result->is_compiled() &&
|
||||||
!function_info->is_toplevel() &&
|
!info->is_toplevel() &&
|
||||||
function_info->allows_lazy_compilation() &&
|
info->allows_lazy_compilation() &&
|
||||||
!function_info->optimization_disabled() &&
|
!info->optimization_disabled() &&
|
||||||
!isolate()->DebuggerHasBreakPoints()) {
|
!isolate()->DebuggerHasBreakPoints()) {
|
||||||
result->MarkForOptimization();
|
result->MarkForOptimization();
|
||||||
}
|
}
|
||||||
@ -1752,8 +1737,9 @@ void Factory::ReinitializeJSReceiver(Handle<JSReceiver> object,
|
|||||||
if (type == JS_FUNCTION_TYPE) {
|
if (type == JS_FUNCTION_TYPE) {
|
||||||
map->set_function_with_prototype(true);
|
map->set_function_with_prototype(true);
|
||||||
Handle<JSFunction> js_function = Handle<JSFunction>::cast(object);
|
Handle<JSFunction> js_function = Handle<JSFunction>::cast(object);
|
||||||
InitializeFunction(js_function, shared.ToHandleChecked(), the_hole_value());
|
Handle<Context> context(isolate()->context()->native_context());
|
||||||
js_function->set_context(isolate()->context()->native_context());
|
InitializeFunction(js_function, shared.ToHandleChecked(),
|
||||||
|
context, null_value());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put in filler if the new object is smaller than the old.
|
// Put in filler if the new object is smaller than the old.
|
||||||
@ -1983,52 +1969,68 @@ Handle<UnseededNumberDictionary> Factory::DictionaryAtNumberPut(
|
|||||||
|
|
||||||
|
|
||||||
void Factory::InitializeFunction(Handle<JSFunction> function,
|
void Factory::InitializeFunction(Handle<JSFunction> function,
|
||||||
Handle<SharedFunctionInfo> shared,
|
Handle<SharedFunctionInfo> info,
|
||||||
Handle<Object> prototype) {
|
Handle<Context> context,
|
||||||
ASSERT(!prototype->IsMap());
|
MaybeHandle<Object> maybe_prototype) {
|
||||||
function->initialize_properties();
|
function->initialize_properties();
|
||||||
function->initialize_elements();
|
function->initialize_elements();
|
||||||
function->set_shared(*shared);
|
function->set_shared(*info);
|
||||||
function->set_code(shared->code());
|
function->set_code(info->code());
|
||||||
|
function->set_context(*context);
|
||||||
|
Handle<Object> prototype;
|
||||||
|
if (maybe_prototype.ToHandle(&prototype)) {
|
||||||
|
ASSERT(!prototype->IsMap());
|
||||||
|
} else {
|
||||||
|
prototype = the_hole_value();
|
||||||
|
}
|
||||||
function->set_prototype_or_initial_map(*prototype);
|
function->set_prototype_or_initial_map(*prototype);
|
||||||
function->set_context(*undefined_value());
|
|
||||||
function->set_literals_or_bindings(*empty_fixed_array());
|
function->set_literals_or_bindings(*empty_fixed_array());
|
||||||
function->set_next_function_link(*undefined_value());
|
function->set_next_function_link(*undefined_value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Handle<JSFunction> Factory::NewFunctionHelper(Handle<Map> function_map,
|
static Handle<Map> MapForNewFunction(Isolate* isolate,
|
||||||
Handle<SharedFunctionInfo> shared,
|
Handle<SharedFunctionInfo> function_info,
|
||||||
Handle<Object> prototype,
|
MaybeHandle<Object> maybe_prototype) {
|
||||||
|
if (maybe_prototype.is_null()) {
|
||||||
|
return function_info->strict_mode() == SLOPPY
|
||||||
|
? isolate->sloppy_function_without_prototype_map()
|
||||||
|
: isolate->strict_function_without_prototype_map();
|
||||||
|
}
|
||||||
|
|
||||||
|
Context* context = isolate->context()->native_context();
|
||||||
|
int map_index = Context::FunctionMapIndex(function_info->strict_mode(),
|
||||||
|
function_info->is_generator());
|
||||||
|
return Handle<Map>(Map::cast(context->get(map_index)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Handle<JSFunction> Factory::NewFunction(Handle<SharedFunctionInfo> info,
|
||||||
|
Handle<Context> context,
|
||||||
|
MaybeHandle<Object> maybe_prototype,
|
||||||
PretenureFlag pretenure) {
|
PretenureFlag pretenure) {
|
||||||
AllocationSpace space =
|
Handle<Map> map = MapForNewFunction(isolate(), info, maybe_prototype);
|
||||||
(pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE;
|
AllocationSpace space = pretenure == TENURED ? OLD_POINTER_SPACE : NEW_SPACE;
|
||||||
Handle<JSFunction> fun = New<JSFunction>(function_map, space);
|
Handle<JSFunction> result = New<JSFunction>(map, space);
|
||||||
InitializeFunction(fun, shared, prototype);
|
InitializeFunction(result, info, context, maybe_prototype);
|
||||||
return fun;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Handle<JSFunction> Factory::NewFunction(Handle<String> name,
|
Handle<JSFunction> Factory::NewFunction(Handle<String> name,
|
||||||
Handle<Object> prototype) {
|
Handle<Object> prototype) {
|
||||||
Handle<SharedFunctionInfo> function_share = NewSharedFunctionInfo(name);
|
Handle<SharedFunctionInfo> info = NewSharedFunctionInfo(name);
|
||||||
Handle<JSFunction> fun = NewFunctionHelper(
|
Handle<Context> context(isolate()->context()->native_context());
|
||||||
isolate()->sloppy_function_map(), function_share, prototype);
|
return NewFunction(info, context, prototype);
|
||||||
fun->set_context(isolate()->context()->native_context());
|
|
||||||
return fun;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Handle<JSFunction> Factory::NewFunctionWithoutPrototype(
|
Handle<JSFunction> Factory::NewFunctionWithoutPrototype(
|
||||||
Handle<String> name,
|
Handle<String> name,
|
||||||
StrictMode strict_mode) {
|
StrictMode strict_mode) {
|
||||||
Handle<SharedFunctionInfo> function_share = NewSharedFunctionInfo(name);
|
Handle<SharedFunctionInfo> info = NewSharedFunctionInfo(name);
|
||||||
Handle<Map> map = strict_mode == SLOPPY
|
Handle<Context> context(isolate()->context()->native_context());
|
||||||
? isolate()->sloppy_function_without_prototype_map()
|
Handle<JSFunction> fun = NewFunction(info, context, MaybeHandle<Object>());
|
||||||
: isolate()->strict_function_without_prototype_map();
|
|
||||||
Handle<JSFunction> fun =
|
|
||||||
NewFunctionHelper(map, function_share, the_hole_value());
|
|
||||||
fun->set_context(isolate()->context()->native_context());
|
|
||||||
return fun;
|
return fun;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2111,12 +2113,8 @@ Handle<JSFunction> Factory::CreateApiFunction(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<JSFunction> result =
|
Handle<JSFunction> result = NewFunction(
|
||||||
NewFunction(Factory::empty_string(),
|
Factory::empty_string(), type, instance_size, code, true);
|
||||||
type,
|
|
||||||
instance_size,
|
|
||||||
code,
|
|
||||||
true);
|
|
||||||
|
|
||||||
// Set length.
|
// Set length.
|
||||||
result->shared()->set_length(obj->length());
|
result->shared()->set_length(obj->length());
|
||||||
|
@ -633,18 +633,18 @@ class Factory V8_FINAL {
|
|||||||
Handle<AllocationSite> allocation_site);
|
Handle<AllocationSite> allocation_site);
|
||||||
|
|
||||||
// Initializes a function with a shared part and prototype.
|
// Initializes a function with a shared part and prototype.
|
||||||
// Note: this code was factored out of NewFunctionHelper such that
|
// Note: this code was factored out of NewFunction such that other parts of
|
||||||
// other parts of the VM could use it. Specifically, a function that creates
|
// the VM could use it. Specifically, a function that creates instances of
|
||||||
// instances of type JS_FUNCTION_TYPE benefit from the use of this function.
|
// type JS_FUNCTION_TYPE benefit from the use of this function.
|
||||||
inline void InitializeFunction(Handle<JSFunction> function,
|
inline void InitializeFunction(Handle<JSFunction> function,
|
||||||
Handle<SharedFunctionInfo> shared,
|
Handle<SharedFunctionInfo> info,
|
||||||
Handle<Object> prototype);
|
Handle<Context> context,
|
||||||
|
MaybeHandle<Object> maybe_prototype);
|
||||||
|
|
||||||
// Creates a function initialized with a shared part.
|
// Creates a function initialized with a shared part.
|
||||||
inline Handle<JSFunction> NewFunctionHelper(
|
inline Handle<JSFunction> NewFunction(Handle<SharedFunctionInfo> info,
|
||||||
Handle<Map> function_map,
|
Handle<Context> context,
|
||||||
Handle<SharedFunctionInfo> shared,
|
MaybeHandle<Object> maybe_prototype,
|
||||||
Handle<Object> prototype,
|
|
||||||
PretenureFlag pretenure = TENURED);
|
PretenureFlag pretenure = TENURED);
|
||||||
|
|
||||||
// Create a new map cache.
|
// Create a new map cache.
|
||||||
|
Loading…
Reference in New Issue
Block a user