OLD | NEW |
---|---|
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "factory.h" | 5 #include "factory.h" |
6 | 6 |
7 #include "macro-assembler.h" | 7 #include "macro-assembler.h" |
8 #include "isolate-inl.h" | 8 #include "isolate-inl.h" |
9 #include "v8conversions.h" | 9 #include "v8conversions.h" |
10 | 10 |
(...skipping 957 matching lines...) Loading... | |
968 CALL_HEAP_FUNCTION(isolate(), array->Copy(), FixedDoubleArray); | 968 CALL_HEAP_FUNCTION(isolate(), array->Copy(), FixedDoubleArray); |
969 } | 969 } |
970 | 970 |
971 | 971 |
972 Handle<ConstantPoolArray> Factory::CopyConstantPoolArray( | 972 Handle<ConstantPoolArray> Factory::CopyConstantPoolArray( |
973 Handle<ConstantPoolArray> array) { | 973 Handle<ConstantPoolArray> array) { |
974 CALL_HEAP_FUNCTION(isolate(), array->Copy(), ConstantPoolArray); | 974 CALL_HEAP_FUNCTION(isolate(), array->Copy(), ConstantPoolArray); |
975 } | 975 } |
976 | 976 |
977 | 977 |
978 static Handle<Map> MapForNewFunction(Isolate *isolate, | |
979 Handle<SharedFunctionInfo> function_info) { | |
980 Context *context = isolate->context()->native_context(); | |
981 int map_index = Context::FunctionMapIndex(function_info->strict_mode(), | |
982 function_info->is_generator()); | |
983 return Handle<Map>(Map::cast(context->get(map_index))); | |
984 } | |
985 | |
986 | |
987 Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo( | 978 Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo( |
988 Handle<SharedFunctionInfo> function_info, | 979 Handle<SharedFunctionInfo> info, |
989 Handle<Context> context, | 980 Handle<Context> context, |
990 PretenureFlag pretenure) { | 981 PretenureFlag pretenure) { |
991 Handle<JSFunction> result = NewFunctionHelper( | 982 Handle<JSFunction> result = NewFunction( |
992 MapForNewFunction(isolate(), function_info), | 983 info, context, the_hole_value(), pretenure); |
993 function_info, | |
994 the_hole_value(), | |
995 pretenure); | |
996 | 984 |
997 if (function_info->ic_age() != isolate()->heap()->global_ic_age()) { | 985 if (info->ic_age() != isolate()->heap()->global_ic_age()) { |
998 function_info->ResetForNewContext(isolate()->heap()->global_ic_age()); | 986 info->ResetForNewContext(isolate()->heap()->global_ic_age()); |
999 } | 987 } |
1000 | 988 |
1001 result->set_context(*context); | 989 int index = info->SearchOptimizedCodeMap(context->native_context(), |
1002 | 990 BailoutId::None()); |
1003 int index = function_info->SearchOptimizedCodeMap(context->native_context(), | 991 if (!info->bound() && index < 0) { |
1004 BailoutId::None()); | 992 int number_of_literals = info->num_literals(); |
1005 if (!function_info->bound() && index < 0) { | |
1006 int number_of_literals = function_info->num_literals(); | |
1007 Handle<FixedArray> literals = NewFixedArray(number_of_literals, pretenure); | 993 Handle<FixedArray> literals = NewFixedArray(number_of_literals, pretenure); |
1008 if (number_of_literals > 0) { | 994 if (number_of_literals > 0) { |
1009 // Store the native context in the literals array prefix. This | 995 // Store the native context in the literals array prefix. This |
1010 // context will be used when creating object, regexp and array | 996 // context will be used when creating object, regexp and array |
1011 // literals in this function. | 997 // literals in this function. |
1012 literals->set(JSFunction::kLiteralNativeContextIndex, | 998 literals->set(JSFunction::kLiteralNativeContextIndex, |
1013 context->native_context()); | 999 context->native_context()); |
1014 } | 1000 } |
1015 result->set_literals(*literals); | 1001 result->set_literals(*literals); |
1016 } | 1002 } |
1017 | 1003 |
1018 if (index > 0) { | 1004 if (index > 0) { |
1019 // Caching of optimized code enabled and optimized code found. | 1005 // Caching of optimized code enabled and optimized code found. |
1020 FixedArray* literals = | 1006 FixedArray* literals = info->GetLiteralsFromOptimizedCodeMap(index); |
1021 function_info->GetLiteralsFromOptimizedCodeMap(index); | |
1022 if (literals != NULL) result->set_literals(literals); | 1007 if (literals != NULL) result->set_literals(literals); |
1023 Code* code = function_info->GetCodeFromOptimizedCodeMap(index); | 1008 Code* code = info->GetCodeFromOptimizedCodeMap(index); |
1024 ASSERT(!code->marked_for_deoptimization()); | 1009 ASSERT(!code->marked_for_deoptimization()); |
1025 result->ReplaceCode(code); | 1010 result->ReplaceCode(code); |
1026 return result; | 1011 return result; |
1027 } | 1012 } |
1028 | 1013 |
1029 if (isolate()->use_crankshaft() && | 1014 if (isolate()->use_crankshaft() && |
1030 FLAG_always_opt && | 1015 FLAG_always_opt && |
1031 result->is_compiled() && | 1016 result->is_compiled() && |
1032 !function_info->is_toplevel() && | 1017 !info->is_toplevel() && |
1033 function_info->allows_lazy_compilation() && | 1018 info->allows_lazy_compilation() && |
1034 !function_info->optimization_disabled() && | 1019 !info->optimization_disabled() && |
1035 !isolate()->DebuggerHasBreakPoints()) { | 1020 !isolate()->DebuggerHasBreakPoints()) { |
1036 result->MarkForOptimization(); | 1021 result->MarkForOptimization(); |
1037 } | 1022 } |
1038 return result; | 1023 return result; |
1039 } | 1024 } |
1040 | 1025 |
1041 | 1026 |
1042 Handle<Object> Factory::NewNumber(double value, | 1027 Handle<Object> Factory::NewNumber(double value, |
1043 PretenureFlag pretenure) { | 1028 PretenureFlag pretenure) { |
1044 // We need to distinguish the minus zero value and this cannot be | 1029 // We need to distinguish the minus zero value and this cannot be |
(...skipping 700 matching lines...) Loading... | |
1745 object->set_map(*map); | 1730 object->set_map(*map); |
1746 Handle<JSObject> jsobj = Handle<JSObject>::cast(object); | 1731 Handle<JSObject> jsobj = Handle<JSObject>::cast(object); |
1747 | 1732 |
1748 // Reinitialize the object from the constructor map. | 1733 // Reinitialize the object from the constructor map. |
1749 heap->InitializeJSObjectFromMap(*jsobj, *properties, *map); | 1734 heap->InitializeJSObjectFromMap(*jsobj, *properties, *map); |
1750 | 1735 |
1751 // Functions require some minimal initialization. | 1736 // Functions require some minimal initialization. |
1752 if (type == JS_FUNCTION_TYPE) { | 1737 if (type == JS_FUNCTION_TYPE) { |
1753 map->set_function_with_prototype(true); | 1738 map->set_function_with_prototype(true); |
1754 Handle<JSFunction> js_function = Handle<JSFunction>::cast(object); | 1739 Handle<JSFunction> js_function = Handle<JSFunction>::cast(object); |
1755 InitializeFunction(js_function, shared.ToHandleChecked(), the_hole_value()); | 1740 Handle<Context> context(isolate()->context()->native_context()); |
1756 js_function->set_context(isolate()->context()->native_context()); | 1741 InitializeFunction(js_function, shared.ToHandleChecked(), |
1742 context, the_hole_value()); | |
Igor Sheludko
2014/04/17 11:10:08
What about passing here an null prototype just to
Toon Verwaest
2014/04/17 11:50:18
Done.
| |
1757 } | 1743 } |
1758 | 1744 |
1759 // Put in filler if the new object is smaller than the old. | 1745 // Put in filler if the new object is smaller than the old. |
1760 if (size_difference > 0) { | 1746 if (size_difference > 0) { |
1761 heap->CreateFillerObjectAt( | 1747 heap->CreateFillerObjectAt( |
1762 object->address() + map->instance_size(), size_difference); | 1748 object->address() + map->instance_size(), size_difference); |
1763 } | 1749 } |
1764 } | 1750 } |
1765 | 1751 |
1766 | 1752 |
(...skipping 209 matching lines...) Loading... | |
1976 Handle<UnseededNumberDictionary> dictionary, | 1962 Handle<UnseededNumberDictionary> dictionary, |
1977 uint32_t key, | 1963 uint32_t key, |
1978 Handle<Object> value) { | 1964 Handle<Object> value) { |
1979 CALL_HEAP_FUNCTION(isolate(), | 1965 CALL_HEAP_FUNCTION(isolate(), |
1980 dictionary->AtNumberPut(key, *value), | 1966 dictionary->AtNumberPut(key, *value), |
1981 UnseededNumberDictionary); | 1967 UnseededNumberDictionary); |
1982 } | 1968 } |
1983 | 1969 |
1984 | 1970 |
1985 void Factory::InitializeFunction(Handle<JSFunction> function, | 1971 void Factory::InitializeFunction(Handle<JSFunction> function, |
1986 Handle<SharedFunctionInfo> shared, | 1972 Handle<SharedFunctionInfo> info, |
1987 Handle<Object> prototype) { | 1973 Handle<Context> context, |
1988 ASSERT(!prototype->IsMap()); | 1974 MaybeHandle<Object> maybe_prototype) { |
1989 function->initialize_properties(); | 1975 function->initialize_properties(); |
1990 function->initialize_elements(); | 1976 function->initialize_elements(); |
1991 function->set_shared(*shared); | 1977 function->set_shared(*info); |
1992 function->set_code(shared->code()); | 1978 function->set_code(info->code()); |
1979 function->set_context(*context); | |
1980 Handle<Object> prototype; | |
1981 if (maybe_prototype.ToHandle(&prototype)) { | |
1982 ASSERT(!prototype->IsMap()); | |
1983 } else { | |
1984 prototype = the_hole_value(); | |
1985 } | |
1993 function->set_prototype_or_initial_map(*prototype); | 1986 function->set_prototype_or_initial_map(*prototype); |
1994 function->set_context(*undefined_value()); | |
1995 function->set_literals_or_bindings(*empty_fixed_array()); | 1987 function->set_literals_or_bindings(*empty_fixed_array()); |
1996 function->set_next_function_link(*undefined_value()); | 1988 function->set_next_function_link(*undefined_value()); |
1997 } | 1989 } |
1998 | 1990 |
1999 | 1991 |
2000 Handle<JSFunction> Factory::NewFunctionHelper(Handle<Map> function_map, | 1992 static Handle<Map> MapForNewFunction(Isolate* isolate, |
2001 Handle<SharedFunctionInfo> shared, | 1993 Handle<SharedFunctionInfo> function_info, |
2002 Handle<Object> prototype, | 1994 MaybeHandle<Object> maybe_prototype) { |
2003 PretenureFlag pretenure) { | 1995 if (maybe_prototype.is_null()) { |
2004 AllocationSpace space = | 1996 return function_info->strict_mode() == SLOPPY |
2005 (pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE; | 1997 ? isolate->sloppy_function_without_prototype_map() |
2006 Handle<JSFunction> fun = New<JSFunction>(function_map, space); | 1998 : isolate->strict_function_without_prototype_map(); |
2007 InitializeFunction(fun, shared, prototype); | 1999 } |
2008 return fun; | 2000 |
2001 Context* context = isolate->context()->native_context(); | |
2002 int map_index = Context::FunctionMapIndex(function_info->strict_mode(), | |
2003 function_info->is_generator()); | |
2004 return Handle<Map>(Map::cast(context->get(map_index))); | |
2005 } | |
2006 | |
2007 | |
2008 Handle<JSFunction> Factory::NewFunction(Handle<SharedFunctionInfo> info, | |
2009 Handle<Context> context, | |
2010 MaybeHandle<Object> maybe_prototype, | |
2011 PretenureFlag pretenure) { | |
2012 Handle<Map> map = MapForNewFunction(isolate(), info, maybe_prototype); | |
2013 AllocationSpace space = pretenure == TENURED ? OLD_POINTER_SPACE : NEW_SPACE; | |
2014 Handle<JSFunction> result = New<JSFunction>(map, space); | |
2015 InitializeFunction(result, info, context, maybe_prototype); | |
2016 return result; | |
2009 } | 2017 } |
2010 | 2018 |
2011 | 2019 |
2012 Handle<JSFunction> Factory::NewFunction(Handle<String> name, | 2020 Handle<JSFunction> Factory::NewFunction(Handle<String> name, |
2013 Handle<Object> prototype) { | 2021 Handle<Object> prototype) { |
2014 Handle<SharedFunctionInfo> function_share = NewSharedFunctionInfo(name); | 2022 Handle<SharedFunctionInfo> info = NewSharedFunctionInfo(name); |
2015 Handle<JSFunction> fun = NewFunctionHelper( | 2023 Handle<Context> context(isolate()->context()->native_context()); |
2016 isolate()->sloppy_function_map(), function_share, prototype); | 2024 return NewFunction(info, context, prototype); |
2017 fun->set_context(isolate()->context()->native_context()); | |
2018 return fun; | |
2019 } | 2025 } |
2020 | 2026 |
2021 | 2027 |
2022 Handle<JSFunction> Factory::NewFunctionWithoutPrototype( | 2028 Handle<JSFunction> Factory::NewFunctionWithoutPrototype( |
2023 Handle<String> name, | 2029 Handle<String> name, |
2024 StrictMode strict_mode) { | 2030 StrictMode strict_mode) { |
2025 Handle<SharedFunctionInfo> function_share = NewSharedFunctionInfo(name); | 2031 Handle<SharedFunctionInfo> info = NewSharedFunctionInfo(name); |
2026 Handle<Map> map = strict_mode == SLOPPY | 2032 Handle<Context> context(isolate()->context()->native_context()); |
2027 ? isolate()->sloppy_function_without_prototype_map() | 2033 Handle<JSFunction> fun = NewFunction(info, context, MaybeHandle<Object>()); |
2028 : isolate()->strict_function_without_prototype_map(); | |
2029 Handle<JSFunction> fun = | |
2030 NewFunctionHelper(map, function_share, the_hole_value()); | |
2031 fun->set_context(isolate()->context()->native_context()); | |
2032 return fun; | 2034 return fun; |
2033 } | 2035 } |
2034 | 2036 |
2035 | 2037 |
2036 #ifdef ENABLE_DEBUGGER_SUPPORT | 2038 #ifdef ENABLE_DEBUGGER_SUPPORT |
2037 Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) { | 2039 Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) { |
2038 // Get the original code of the function. | 2040 // Get the original code of the function. |
2039 Handle<Code> code(shared->code()); | 2041 Handle<Code> code(shared->code()); |
2040 | 2042 |
2041 // Create a copy of the code before allocating the debug info object to avoid | 2043 // Create a copy of the code before allocating the debug info object to avoid |
(...skipping 62 matching lines...) Loading... | |
2104 case OuterGlobalObject: | 2106 case OuterGlobalObject: |
2105 type = JS_GLOBAL_PROXY_TYPE; | 2107 type = JS_GLOBAL_PROXY_TYPE; |
2106 instance_size += JSGlobalProxy::kSize; | 2108 instance_size += JSGlobalProxy::kSize; |
2107 break; | 2109 break; |
2108 default: | 2110 default: |
2109 UNREACHABLE(); | 2111 UNREACHABLE(); |
2110 type = JS_OBJECT_TYPE; // Keep the compiler happy. | 2112 type = JS_OBJECT_TYPE; // Keep the compiler happy. |
2111 break; | 2113 break; |
2112 } | 2114 } |
2113 | 2115 |
2114 Handle<JSFunction> result = | 2116 Handle<JSFunction> result = NewFunction( |
2115 NewFunction(Factory::empty_string(), | 2117 Factory::empty_string(), type, instance_size, code, true); |
2116 type, | |
2117 instance_size, | |
2118 code, | |
2119 true); | |
2120 | 2118 |
2121 // Set length. | 2119 // Set length. |
2122 result->shared()->set_length(obj->length()); | 2120 result->shared()->set_length(obj->length()); |
2123 | 2121 |
2124 // Set class name. | 2122 // Set class name. |
2125 Handle<Object> class_name = Handle<Object>(obj->class_name(), isolate()); | 2123 Handle<Object> class_name = Handle<Object>(obj->class_name(), isolate()); |
2126 if (class_name->IsString()) { | 2124 if (class_name->IsString()) { |
2127 result->shared()->set_instance_class_name(*class_name); | 2125 result->shared()->set_instance_class_name(*class_name); |
2128 result->shared()->set_name(*class_name); | 2126 result->shared()->set_name(*class_name); |
2129 } | 2127 } |
(...skipping 201 matching lines...) Loading... | |
2331 if (String::Equals(name, infinity_string())) return infinity_value(); | 2329 if (String::Equals(name, infinity_string())) return infinity_value(); |
2332 return Handle<Object>::null(); | 2330 return Handle<Object>::null(); |
2333 } | 2331 } |
2334 | 2332 |
2335 | 2333 |
2336 Handle<Object> Factory::ToBoolean(bool value) { | 2334 Handle<Object> Factory::ToBoolean(bool value) { |
2337 return value ? true_value() : false_value(); | 2335 return value ? true_value() : false_value(); |
2338 } | 2336 } |
2339 | 2337 |
2340 } } // namespace v8::internal | 2338 } } // namespace v8::internal |
OLD | NEW |