Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(415)

Side by Side Diff: src/factory.cc

Issue 263083008: Pass in the map while creating JSFunction, and set prototype in the client. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/factory.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "conversions.h" 7 #include "conversions.h"
8 #include "isolate-inl.h" 8 #include "isolate-inl.h"
9 #include "macro-assembler.h" 9 #include "macro-assembler.h"
10 10
(...skipping 888 matching lines...) Expand 10 before | Expand all | Expand 10 after
899 Handle<Map> Factory::NewMap(InstanceType type, 899 Handle<Map> Factory::NewMap(InstanceType type,
900 int instance_size, 900 int instance_size,
901 ElementsKind elements_kind) { 901 ElementsKind elements_kind) {
902 CALL_HEAP_FUNCTION( 902 CALL_HEAP_FUNCTION(
903 isolate(), 903 isolate(),
904 isolate()->heap()->AllocateMap(type, instance_size, elements_kind), 904 isolate()->heap()->AllocateMap(type, instance_size, elements_kind),
905 Map); 905 Map);
906 } 906 }
907 907
908 908
909 Handle<JSObject> Factory::NewFunctionPrototype(Handle<JSFunction> function) {
910 // Make sure to use globals from the function's context, since the function
911 // can be from a different context.
912 Handle<Context> native_context(function->context()->native_context());
913 Handle<Map> new_map;
914 if (function->shared()->is_generator()) {
915 // Generator prototypes can share maps since they don't have "constructor"
916 // properties.
917 new_map = handle(native_context->generator_object_prototype_map());
918 } else {
919 // Each function prototype gets a fresh map to avoid unwanted sharing of
920 // maps between prototypes of different constructors.
921 Handle<JSFunction> object_function(native_context->object_function());
922 ASSERT(object_function->has_initial_map());
923 new_map = Map::Copy(handle(object_function->initial_map()));
924 }
925
926 Handle<JSObject> prototype = NewJSObjectFromMap(new_map);
927
928 if (!function->shared()->is_generator()) {
929 JSObject::SetLocalPropertyIgnoreAttributes(prototype,
930 constructor_string(),
931 function,
932 DONT_ENUM).Assert();
933 }
934
935 return prototype;
936 }
937
938
939 Handle<JSObject> Factory::CopyJSObject(Handle<JSObject> object) { 909 Handle<JSObject> Factory::CopyJSObject(Handle<JSObject> object) {
940 CALL_HEAP_FUNCTION(isolate(), 910 CALL_HEAP_FUNCTION(isolate(),
941 isolate()->heap()->CopyJSObject(*object, NULL), 911 isolate()->heap()->CopyJSObject(*object, NULL),
942 JSObject); 912 JSObject);
943 } 913 }
944 914
945 915
946 Handle<JSObject> Factory::CopyJSObjectWithAllocationSite( 916 Handle<JSObject> Factory::CopyJSObjectWithAllocationSite(
947 Handle<JSObject> object, 917 Handle<JSObject> object,
948 Handle<AllocationSite> site) { 918 Handle<AllocationSite> site) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
987 957
988 958
989 Handle<ConstantPoolArray> Factory::CopyConstantPoolArray( 959 Handle<ConstantPoolArray> Factory::CopyConstantPoolArray(
990 Handle<ConstantPoolArray> array) { 960 Handle<ConstantPoolArray> array) {
991 CALL_HEAP_FUNCTION(isolate(), 961 CALL_HEAP_FUNCTION(isolate(),
992 isolate()->heap()->CopyConstantPoolArray(*array), 962 isolate()->heap()->CopyConstantPoolArray(*array),
993 ConstantPoolArray); 963 ConstantPoolArray);
994 } 964 }
995 965
996 966
997 Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
998 Handle<SharedFunctionInfo> info,
999 Handle<Context> context,
1000 PretenureFlag pretenure) {
1001 Handle<JSFunction> result = NewFunction(
1002 info, context, the_hole_value(), pretenure);
1003
1004 if (info->ic_age() != isolate()->heap()->global_ic_age()) {
1005 info->ResetForNewContext(isolate()->heap()->global_ic_age());
1006 }
1007
1008 int index = info->SearchOptimizedCodeMap(context->native_context(),
1009 BailoutId::None());
1010 if (!info->bound() && index < 0) {
1011 int number_of_literals = info->num_literals();
1012 Handle<FixedArray> literals = NewFixedArray(number_of_literals, pretenure);
1013 if (number_of_literals > 0) {
1014 // Store the native context in the literals array prefix. This
1015 // context will be used when creating object, regexp and array
1016 // literals in this function.
1017 literals->set(JSFunction::kLiteralNativeContextIndex,
1018 context->native_context());
1019 }
1020 result->set_literals(*literals);
1021 }
1022
1023 if (index > 0) {
1024 // Caching of optimized code enabled and optimized code found.
1025 FixedArray* literals = info->GetLiteralsFromOptimizedCodeMap(index);
1026 if (literals != NULL) result->set_literals(literals);
1027 Code* code = info->GetCodeFromOptimizedCodeMap(index);
1028 ASSERT(!code->marked_for_deoptimization());
1029 result->ReplaceCode(code);
1030 return result;
1031 }
1032
1033 if (isolate()->use_crankshaft() &&
1034 FLAG_always_opt &&
1035 result->is_compiled() &&
1036 !info->is_toplevel() &&
1037 info->allows_lazy_compilation() &&
1038 !info->optimization_disabled() &&
1039 !isolate()->DebuggerHasBreakPoints()) {
1040 result->MarkForOptimization();
1041 }
1042 return result;
1043 }
1044
1045
1046 Handle<Object> Factory::NewNumber(double value, 967 Handle<Object> Factory::NewNumber(double value,
1047 PretenureFlag pretenure) { 968 PretenureFlag pretenure) {
1048 // We need to distinguish the minus zero value and this cannot be 969 // We need to distinguish the minus zero value and this cannot be
1049 // done after conversion to int. Doing this by comparing bit 970 // done after conversion to int. Doing this by comparing bit
1050 // patterns is faster than using fpclassify() et al. 971 // patterns is faster than using fpclassify() et al.
1051 if (IsMinusZero(value)) return NewHeapNumber(-0.0, pretenure); 972 if (IsMinusZero(value)) return NewHeapNumber(-0.0, pretenure);
1052 973
1053 int int_value = FastD2I(value); 974 int int_value = FastD2I(value);
1054 if (value == int_value && Smi::IsValid(int_value)) { 975 if (value == int_value && Smi::IsValid(int_value)) {
1055 return handle(Smi::FromInt(int_value), isolate()); 976 return handle(Smi::FromInt(int_value), isolate());
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
1249 isolate()->js_builtins_object(), 1170 isolate()->js_builtins_object(),
1250 ARRAY_SIZE(argv), 1171 ARRAY_SIZE(argv),
1251 argv, 1172 argv,
1252 &exception).ToHandle(&result)) { 1173 &exception).ToHandle(&result)) {
1253 return exception; 1174 return exception;
1254 } 1175 }
1255 return result; 1176 return result;
1256 } 1177 }
1257 1178
1258 1179
1180 void Factory::InitializeFunction(Handle<JSFunction> function,
1181 Handle<SharedFunctionInfo> info,
1182 Handle<Context> context) {
1183 function->initialize_properties();
1184 function->initialize_elements();
1185 function->set_shared(*info);
1186 function->set_code(info->code());
1187 function->set_context(*context);
1188 function->set_prototype_or_initial_map(*the_hole_value());
1189 function->set_literals_or_bindings(*empty_fixed_array());
1190 function->set_next_function_link(*undefined_value());
1191 }
1192
1193
1194 Handle<JSFunction> Factory::NewFunction(Handle<Map> map,
1195 Handle<SharedFunctionInfo> info,
1196 Handle<Context> context,
1197 PretenureFlag pretenure) {
1198 AllocationSpace space = pretenure == TENURED ? OLD_POINTER_SPACE : NEW_SPACE;
1199 Handle<JSFunction> result = New<JSFunction>(map, space);
1200 InitializeFunction(result, info, context);
1201 return result;
1202 }
1203
1204
1205 Handle<JSFunction> Factory::NewFunction(Handle<String> name,
1206 Handle<Code> code,
1207 MaybeHandle<Object> maybe_prototype) {
1208 Handle<SharedFunctionInfo> info = NewSharedFunctionInfo(name);
1209 ASSERT(info->strict_mode() == SLOPPY);
1210 info->set_code(*code);
1211 Handle<Context> context(isolate()->context()->native_context());
1212 Handle<Map> map = maybe_prototype.is_null()
1213 ? isolate()->sloppy_function_without_prototype_map()
1214 : isolate()->sloppy_function_map();
1215 Handle<JSFunction> result = NewFunction(map, info, context);
1216 Handle<Object> prototype;
1217 if (maybe_prototype.ToHandle(&prototype)) {
1218 result->set_prototype_or_initial_map(*prototype);
1219 }
1220 return result;
1221 }
1222
1223
1224 Handle<JSFunction> Factory::NewFunctionWithPrototype(Handle<String> name,
1225 Handle<Object> prototype) {
1226 Handle<SharedFunctionInfo> info = NewSharedFunctionInfo(name);
1227 ASSERT(info->strict_mode() == SLOPPY);
1228 Handle<Context> context(isolate()->context()->native_context());
1229 Handle<Map> map = isolate()->sloppy_function_map();
1230 Handle<JSFunction> result = NewFunction(map, info, context);
1231 result->set_prototype_or_initial_map(*prototype);
1232 return result;
1233 }
1234
1235
1259 Handle<JSFunction> Factory::NewFunction(MaybeHandle<Object> maybe_prototype, 1236 Handle<JSFunction> Factory::NewFunction(MaybeHandle<Object> maybe_prototype,
1260 Handle<String> name, 1237 Handle<String> name,
1261 InstanceType type, 1238 InstanceType type,
1262 int instance_size, 1239 int instance_size,
1263 Handle<Code> code, 1240 Handle<Code> code,
1264 bool force_initial_map) { 1241 bool force_initial_map) {
1265 // Allocate the function 1242 // Allocate the function
1266 Handle<JSFunction> function = NewFunction(name, code, maybe_prototype); 1243 Handle<JSFunction> function = NewFunction(name, code, maybe_prototype);
1267 1244
1268 Handle<Object> prototype; 1245 Handle<Object> prototype;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1319 GetInitialFastElementsKind()); 1296 GetInitialFastElementsKind());
1320 function->set_initial_map(*initial_map); 1297 function->set_initial_map(*initial_map);
1321 initial_map->set_constructor(*function); 1298 initial_map->set_constructor(*function);
1322 } 1299 }
1323 1300
1324 JSFunction::SetPrototype(function, prototype); 1301 JSFunction::SetPrototype(function, prototype);
1325 return function; 1302 return function;
1326 } 1303 }
1327 1304
1328 1305
1306 Handle<JSObject> Factory::NewFunctionPrototype(Handle<JSFunction> function) {
1307 // Make sure to use globals from the function's context, since the function
1308 // can be from a different context.
1309 Handle<Context> native_context(function->context()->native_context());
1310 Handle<Map> new_map;
1311 if (function->shared()->is_generator()) {
1312 // Generator prototypes can share maps since they don't have "constructor"
1313 // properties.
1314 new_map = handle(native_context->generator_object_prototype_map());
1315 } else {
1316 // Each function prototype gets a fresh map to avoid unwanted sharing of
1317 // maps between prototypes of different constructors.
1318 Handle<JSFunction> object_function(native_context->object_function());
1319 ASSERT(object_function->has_initial_map());
1320 new_map = Map::Copy(handle(object_function->initial_map()));
1321 }
1322
1323 Handle<JSObject> prototype = NewJSObjectFromMap(new_map);
1324
1325 if (!function->shared()->is_generator()) {
1326 JSObject::SetLocalPropertyIgnoreAttributes(prototype,
1327 constructor_string(),
1328 function,
1329 DONT_ENUM).Assert();
1330 }
1331
1332 return prototype;
1333 }
1334
1335
1336 Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
1337 Handle<SharedFunctionInfo> info,
1338 Handle<Context> context,
1339 PretenureFlag pretenure) {
1340 int map_index = Context::FunctionMapIndex(info->strict_mode(),
1341 info->is_generator());
1342 Handle<Map> map(Map::cast(context->native_context()->get(map_index)));
1343 Handle<JSFunction> result = NewFunction(map, info, context, pretenure);
1344
1345 if (info->ic_age() != isolate()->heap()->global_ic_age()) {
1346 info->ResetForNewContext(isolate()->heap()->global_ic_age());
1347 }
1348
1349 int index = info->SearchOptimizedCodeMap(context->native_context(),
1350 BailoutId::None());
1351 if (!info->bound() && index < 0) {
1352 int number_of_literals = info->num_literals();
1353 Handle<FixedArray> literals = NewFixedArray(number_of_literals, pretenure);
1354 if (number_of_literals > 0) {
1355 // Store the native context in the literals array prefix. This
1356 // context will be used when creating object, regexp and array
1357 // literals in this function.
1358 literals->set(JSFunction::kLiteralNativeContextIndex,
1359 context->native_context());
1360 }
1361 result->set_literals(*literals);
1362 }
1363
1364 if (index > 0) {
1365 // Caching of optimized code enabled and optimized code found.
1366 FixedArray* literals = info->GetLiteralsFromOptimizedCodeMap(index);
1367 if (literals != NULL) result->set_literals(literals);
1368 Code* code = info->GetCodeFromOptimizedCodeMap(index);
1369 ASSERT(!code->marked_for_deoptimization());
1370 result->ReplaceCode(code);
1371 return result;
1372 }
1373
1374 if (isolate()->use_crankshaft() &&
1375 FLAG_always_opt &&
1376 result->is_compiled() &&
1377 !info->is_toplevel() &&
1378 info->allows_lazy_compilation() &&
1379 !info->optimization_disabled() &&
1380 !isolate()->DebuggerHasBreakPoints()) {
1381 result->MarkForOptimization();
1382 }
1383 return result;
1384 }
1385
1386
1329 Handle<JSObject> Factory::NewIteratorResultObject(Handle<Object> value, 1387 Handle<JSObject> Factory::NewIteratorResultObject(Handle<Object> value,
1330 bool done) { 1388 bool done) {
1331 Handle<Map> map(isolate()->native_context()->iterator_result_map()); 1389 Handle<Map> map(isolate()->native_context()->iterator_result_map());
1332 Handle<JSObject> result = NewJSObjectFromMap(map, NOT_TENURED, false); 1390 Handle<JSObject> result = NewJSObjectFromMap(map, NOT_TENURED, false);
1333 result->InObjectPropertyAtPut( 1391 result->InObjectPropertyAtPut(
1334 JSGeneratorObject::kResultValuePropertyIndex, *value); 1392 JSGeneratorObject::kResultValuePropertyIndex, *value);
1335 result->InObjectPropertyAtPut( 1393 result->InObjectPropertyAtPut(
1336 JSGeneratorObject::kResultDonePropertyIndex, *ToBoolean(done)); 1394 JSGeneratorObject::kResultDonePropertyIndex, *ToBoolean(done));
1337 return result; 1395 return result;
1338 } 1396 }
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
1752 Handle<JSObject> jsobj = Handle<JSObject>::cast(object); 1810 Handle<JSObject> jsobj = Handle<JSObject>::cast(object);
1753 1811
1754 // Reinitialize the object from the constructor map. 1812 // Reinitialize the object from the constructor map.
1755 heap->InitializeJSObjectFromMap(*jsobj, *properties, *map); 1813 heap->InitializeJSObjectFromMap(*jsobj, *properties, *map);
1756 1814
1757 // Functions require some minimal initialization. 1815 // Functions require some minimal initialization.
1758 if (type == JS_FUNCTION_TYPE) { 1816 if (type == JS_FUNCTION_TYPE) {
1759 map->set_function_with_prototype(true); 1817 map->set_function_with_prototype(true);
1760 Handle<JSFunction> js_function = Handle<JSFunction>::cast(object); 1818 Handle<JSFunction> js_function = Handle<JSFunction>::cast(object);
1761 Handle<Context> context(isolate()->context()->native_context()); 1819 Handle<Context> context(isolate()->context()->native_context());
1762 InitializeFunction(js_function, shared.ToHandleChecked(), 1820 InitializeFunction(js_function, shared.ToHandleChecked(), context);
1763 context, null_value());
1764 } 1821 }
1765 1822
1766 // Put in filler if the new object is smaller than the old. 1823 // Put in filler if the new object is smaller than the old.
1767 if (size_difference > 0) { 1824 if (size_difference > 0) {
1768 heap->CreateFillerObjectAt( 1825 heap->CreateFillerObjectAt(
1769 object->address() + map->instance_size(), size_difference); 1826 object->address() + map->instance_size(), size_difference);
1770 } 1827 }
1771 } 1828 }
1772 1829
1773 1830
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
1987 } 2044 }
1988 2045
1989 // We tenure the allocated string since it is referenced from the 2046 // We tenure the allocated string since it is referenced from the
1990 // number-string cache which lives in the old space. 2047 // number-string cache which lives in the old space.
1991 Handle<String> js_string = NewStringFromAsciiChecked(str, TENURED); 2048 Handle<String> js_string = NewStringFromAsciiChecked(str, TENURED);
1992 SetNumberStringCache(number, js_string); 2049 SetNumberStringCache(number, js_string);
1993 return js_string; 2050 return js_string;
1994 } 2051 }
1995 2052
1996 2053
1997 void Factory::InitializeFunction(Handle<JSFunction> function,
1998 Handle<SharedFunctionInfo> info,
1999 Handle<Context> context,
2000 MaybeHandle<Object> maybe_prototype) {
2001 function->initialize_properties();
2002 function->initialize_elements();
2003 function->set_shared(*info);
2004 function->set_code(info->code());
2005 function->set_context(*context);
2006 Handle<Object> prototype;
2007 if (maybe_prototype.ToHandle(&prototype)) {
2008 ASSERT(!prototype->IsMap());
2009 } else {
2010 prototype = the_hole_value();
2011 }
2012 function->set_prototype_or_initial_map(*prototype);
2013 function->set_literals_or_bindings(*empty_fixed_array());
2014 function->set_next_function_link(*undefined_value());
2015 }
2016
2017
2018 static Handle<Map> MapForNewFunction(Isolate* isolate,
2019 Handle<SharedFunctionInfo> function_info,
2020 MaybeHandle<Object> maybe_prototype) {
2021 if (maybe_prototype.is_null()) {
2022 return function_info->strict_mode() == SLOPPY
2023 ? isolate->sloppy_function_without_prototype_map()
2024 : isolate->strict_function_without_prototype_map();
2025 }
2026
2027 Context* context = isolate->context()->native_context();
2028 int map_index = Context::FunctionMapIndex(function_info->strict_mode(),
2029 function_info->is_generator());
2030 return Handle<Map>(Map::cast(context->get(map_index)));
2031 }
2032
2033
2034 Handle<JSFunction> Factory::NewFunction(Handle<SharedFunctionInfo> info,
2035 Handle<Context> context,
2036 MaybeHandle<Object> maybe_prototype,
2037 PretenureFlag pretenure) {
2038 Handle<Map> map = MapForNewFunction(isolate(), info, maybe_prototype);
2039 AllocationSpace space = pretenure == TENURED ? OLD_POINTER_SPACE : NEW_SPACE;
2040 Handle<JSFunction> result = New<JSFunction>(map, space);
2041 InitializeFunction(result, info, context, maybe_prototype);
2042 return result;
2043 }
2044
2045
2046 Handle<JSFunction> Factory::NewFunction(Handle<String> name,
2047 Handle<Code> code,
2048 MaybeHandle<Object> maybe_prototype) {
2049 Handle<SharedFunctionInfo> info = NewSharedFunctionInfo(name);
2050 info->set_code(*code);
2051 Handle<Context> context(isolate()->context()->native_context());
2052 return NewFunction(info, context, maybe_prototype);
2053 }
2054
2055
2056 Handle<JSFunction> Factory::NewFunctionWithPrototype(Handle<String> name,
2057 Handle<Object> prototype) {
2058 Handle<SharedFunctionInfo> info = NewSharedFunctionInfo(name);
2059 Handle<Context> context(isolate()->context()->native_context());
2060 return NewFunction(info, context, prototype);
2061 }
2062
2063
2064 Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) { 2054 Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) {
2065 // Get the original code of the function. 2055 // Get the original code of the function.
2066 Handle<Code> code(shared->code()); 2056 Handle<Code> code(shared->code());
2067 2057
2068 // Create a copy of the code before allocating the debug info object to avoid 2058 // Create a copy of the code before allocating the debug info object to avoid
2069 // allocation while setting up the debug info object. 2059 // allocation while setting up the debug info object.
2070 Handle<Code> original_code(*Factory::CopyCode(code)); 2060 Handle<Code> original_code(*Factory::CopyCode(code));
2071 2061
2072 // Allocate initial fixed array for active break points before allocating the 2062 // Allocate initial fixed array for active break points before allocating the
2073 // debug info object to avoid allocation while setting up the debug info 2063 // debug info object to avoid allocation while setting up the debug info
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
2355 return Handle<Object>::null(); 2345 return Handle<Object>::null();
2356 } 2346 }
2357 2347
2358 2348
2359 Handle<Object> Factory::ToBoolean(bool value) { 2349 Handle<Object> Factory::ToBoolean(bool value) {
2360 return value ? true_value() : false_value(); 2350 return value ? true_value() : false_value();
2361 } 2351 }
2362 2352
2363 2353
2364 } } // namespace v8::internal 2354 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/factory.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698