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

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: 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 info->set_code(*code);
1210 Handle<Context> context(isolate()->context()->native_context());
Igor Sheludko 2014/05/05 16:11:35 Does it make sense to add ASSERT(info->strict_mode
1211 Handle<Map> map = maybe_prototype.is_null()
1212 ? isolate()->sloppy_function_without_prototype_map()
1213 : isolate()->sloppy_function_map();
1214 Handle<JSFunction> result = NewFunction(map, info, context);
1215 Handle<Object> prototype;
1216 if (maybe_prototype.ToHandle(&prototype)) {
1217 result->set_prototype_or_initial_map(*prototype);
1218 }
1219 return result;
1220 }
1221
1222
1223 Handle<JSFunction> Factory::NewFunctionWithPrototype(Handle<String> name,
1224 Handle<Object> prototype) {
1225 Handle<SharedFunctionInfo> info = NewSharedFunctionInfo(name);
1226 Handle<Context> context(isolate()->context()->native_context());
Igor Sheludko 2014/05/05 16:11:35 ... and here?
1227 Handle<Map> map = isolate()->sloppy_function_map();
1228 Handle<JSFunction> result = NewFunction(map, info, context);
1229 result->set_prototype_or_initial_map(*prototype);
1230 return result;
1231 }
1232
1233
1259 Handle<JSFunction> Factory::NewFunction(MaybeHandle<Object> maybe_prototype, 1234 Handle<JSFunction> Factory::NewFunction(MaybeHandle<Object> maybe_prototype,
1260 Handle<String> name, 1235 Handle<String> name,
1261 InstanceType type, 1236 InstanceType type,
1262 int instance_size, 1237 int instance_size,
1263 Handle<Code> code, 1238 Handle<Code> code,
1264 bool force_initial_map) { 1239 bool force_initial_map) {
1265 // Allocate the function 1240 // Allocate the function
1266 Handle<JSFunction> function = NewFunction(name, code, maybe_prototype); 1241 Handle<JSFunction> function = NewFunction(name, code, maybe_prototype);
1267 1242
1268 Handle<Object> prototype; 1243 Handle<Object> prototype;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1319 GetInitialFastElementsKind()); 1294 GetInitialFastElementsKind());
1320 function->set_initial_map(*initial_map); 1295 function->set_initial_map(*initial_map);
1321 initial_map->set_constructor(*function); 1296 initial_map->set_constructor(*function);
1322 } 1297 }
1323 1298
1324 JSFunction::SetPrototype(function, prototype); 1299 JSFunction::SetPrototype(function, prototype);
1325 return function; 1300 return function;
1326 } 1301 }
1327 1302
1328 1303
1304 Handle<JSObject> Factory::NewFunctionPrototype(Handle<JSFunction> function) {
1305 // Make sure to use globals from the function's context, since the function
1306 // can be from a different context.
1307 Handle<Context> native_context(function->context()->native_context());
1308 Handle<Map> new_map;
1309 if (function->shared()->is_generator()) {
1310 // Generator prototypes can share maps since they don't have "constructor"
1311 // properties.
1312 new_map = handle(native_context->generator_object_prototype_map());
1313 } else {
1314 // Each function prototype gets a fresh map to avoid unwanted sharing of
1315 // maps between prototypes of different constructors.
1316 Handle<JSFunction> object_function(native_context->object_function());
1317 ASSERT(object_function->has_initial_map());
1318 new_map = Map::Copy(handle(object_function->initial_map()));
1319 }
1320
1321 Handle<JSObject> prototype = NewJSObjectFromMap(new_map);
1322
1323 if (!function->shared()->is_generator()) {
1324 JSObject::SetLocalPropertyIgnoreAttributes(prototype,
1325 constructor_string(),
1326 function,
1327 DONT_ENUM).Assert();
1328 }
1329
1330 return prototype;
1331 }
1332
1333
1334 static Handle<Map> MapForNewFunction(Isolate* isolate,
1335 Handle<SharedFunctionInfo> function_info) {
1336 Context* context = isolate->context()->native_context();
1337 int map_index = Context::FunctionMapIndex(function_info->strict_mode(),
1338 function_info->is_generator());
1339 return Handle<Map>(Map::cast(context->get(map_index)));
1340 }
1341
1342
1343 Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
1344 Handle<SharedFunctionInfo> info,
1345 Handle<Context> context,
1346 PretenureFlag pretenure) {
1347 Handle<Map> map = MapForNewFunction(isolate(), info);
Igor Sheludko 2014/05/05 16:11:35 Since this is the only caller of MapForNewFunction
1348 Handle<JSFunction> result = NewFunction(map, info, context, pretenure);
1349
1350 if (info->ic_age() != isolate()->heap()->global_ic_age()) {
1351 info->ResetForNewContext(isolate()->heap()->global_ic_age());
1352 }
1353
1354 int index = info->SearchOptimizedCodeMap(context->native_context(),
1355 BailoutId::None());
1356 if (!info->bound() && index < 0) {
1357 int number_of_literals = info->num_literals();
1358 Handle<FixedArray> literals = NewFixedArray(number_of_literals, pretenure);
1359 if (number_of_literals > 0) {
1360 // Store the native context in the literals array prefix. This
1361 // context will be used when creating object, regexp and array
1362 // literals in this function.
1363 literals->set(JSFunction::kLiteralNativeContextIndex,
1364 context->native_context());
1365 }
1366 result->set_literals(*literals);
1367 }
1368
1369 if (index > 0) {
1370 // Caching of optimized code enabled and optimized code found.
1371 FixedArray* literals = info->GetLiteralsFromOptimizedCodeMap(index);
1372 if (literals != NULL) result->set_literals(literals);
1373 Code* code = info->GetCodeFromOptimizedCodeMap(index);
1374 ASSERT(!code->marked_for_deoptimization());
1375 result->ReplaceCode(code);
1376 return result;
1377 }
1378
1379 if (isolate()->use_crankshaft() &&
1380 FLAG_always_opt &&
1381 result->is_compiled() &&
1382 !info->is_toplevel() &&
1383 info->allows_lazy_compilation() &&
1384 !info->optimization_disabled() &&
1385 !isolate()->DebuggerHasBreakPoints()) {
1386 result->MarkForOptimization();
1387 }
1388 return result;
1389 }
1390
1391
1329 Handle<JSObject> Factory::NewIteratorResultObject(Handle<Object> value, 1392 Handle<JSObject> Factory::NewIteratorResultObject(Handle<Object> value,
1330 bool done) { 1393 bool done) {
1331 Handle<Map> map(isolate()->native_context()->iterator_result_map()); 1394 Handle<Map> map(isolate()->native_context()->iterator_result_map());
1332 Handle<JSObject> result = NewJSObjectFromMap(map, NOT_TENURED, false); 1395 Handle<JSObject> result = NewJSObjectFromMap(map, NOT_TENURED, false);
1333 result->InObjectPropertyAtPut( 1396 result->InObjectPropertyAtPut(
1334 JSGeneratorObject::kResultValuePropertyIndex, *value); 1397 JSGeneratorObject::kResultValuePropertyIndex, *value);
1335 result->InObjectPropertyAtPut( 1398 result->InObjectPropertyAtPut(
1336 JSGeneratorObject::kResultDonePropertyIndex, *ToBoolean(done)); 1399 JSGeneratorObject::kResultDonePropertyIndex, *ToBoolean(done));
1337 return result; 1400 return result;
1338 } 1401 }
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
1752 Handle<JSObject> jsobj = Handle<JSObject>::cast(object); 1815 Handle<JSObject> jsobj = Handle<JSObject>::cast(object);
1753 1816
1754 // Reinitialize the object from the constructor map. 1817 // Reinitialize the object from the constructor map.
1755 heap->InitializeJSObjectFromMap(*jsobj, *properties, *map); 1818 heap->InitializeJSObjectFromMap(*jsobj, *properties, *map);
1756 1819
1757 // Functions require some minimal initialization. 1820 // Functions require some minimal initialization.
1758 if (type == JS_FUNCTION_TYPE) { 1821 if (type == JS_FUNCTION_TYPE) {
1759 map->set_function_with_prototype(true); 1822 map->set_function_with_prototype(true);
1760 Handle<JSFunction> js_function = Handle<JSFunction>::cast(object); 1823 Handle<JSFunction> js_function = Handle<JSFunction>::cast(object);
1761 Handle<Context> context(isolate()->context()->native_context()); 1824 Handle<Context> context(isolate()->context()->native_context());
1762 InitializeFunction(js_function, shared.ToHandleChecked(), 1825 InitializeFunction(js_function, shared.ToHandleChecked(), context);
1763 context, null_value());
1764 } 1826 }
1765 1827
1766 // Put in filler if the new object is smaller than the old. 1828 // Put in filler if the new object is smaller than the old.
1767 if (size_difference > 0) { 1829 if (size_difference > 0) {
1768 heap->CreateFillerObjectAt( 1830 heap->CreateFillerObjectAt(
1769 object->address() + map->instance_size(), size_difference); 1831 object->address() + map->instance_size(), size_difference);
1770 } 1832 }
1771 } 1833 }
1772 1834
1773 1835
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
1981 } 2043 }
1982 2044
1983 // We tenure the allocated string since it is referenced from the 2045 // We tenure the allocated string since it is referenced from the
1984 // number-string cache which lives in the old space. 2046 // number-string cache which lives in the old space.
1985 Handle<String> js_string = NewStringFromAsciiChecked(str, TENURED); 2047 Handle<String> js_string = NewStringFromAsciiChecked(str, TENURED);
1986 SetNumberStringCache(number, js_string); 2048 SetNumberStringCache(number, js_string);
1987 return js_string; 2049 return js_string;
1988 } 2050 }
1989 2051
1990 2052
1991 void Factory::InitializeFunction(Handle<JSFunction> function,
1992 Handle<SharedFunctionInfo> info,
1993 Handle<Context> context,
1994 MaybeHandle<Object> maybe_prototype) {
1995 function->initialize_properties();
1996 function->initialize_elements();
1997 function->set_shared(*info);
1998 function->set_code(info->code());
1999 function->set_context(*context);
2000 Handle<Object> prototype;
2001 if (maybe_prototype.ToHandle(&prototype)) {
2002 ASSERT(!prototype->IsMap());
2003 } else {
2004 prototype = the_hole_value();
2005 }
2006 function->set_prototype_or_initial_map(*prototype);
2007 function->set_literals_or_bindings(*empty_fixed_array());
2008 function->set_next_function_link(*undefined_value());
2009 }
2010
2011
2012 static Handle<Map> MapForNewFunction(Isolate* isolate,
2013 Handle<SharedFunctionInfo> function_info,
2014 MaybeHandle<Object> maybe_prototype) {
2015 if (maybe_prototype.is_null()) {
2016 return function_info->strict_mode() == SLOPPY
2017 ? isolate->sloppy_function_without_prototype_map()
2018 : isolate->strict_function_without_prototype_map();
2019 }
2020
2021 Context* context = isolate->context()->native_context();
2022 int map_index = Context::FunctionMapIndex(function_info->strict_mode(),
2023 function_info->is_generator());
2024 return Handle<Map>(Map::cast(context->get(map_index)));
2025 }
2026
2027
2028 Handle<JSFunction> Factory::NewFunction(Handle<SharedFunctionInfo> info,
2029 Handle<Context> context,
2030 MaybeHandle<Object> maybe_prototype,
2031 PretenureFlag pretenure) {
2032 Handle<Map> map = MapForNewFunction(isolate(), info, maybe_prototype);
2033 AllocationSpace space = pretenure == TENURED ? OLD_POINTER_SPACE : NEW_SPACE;
2034 Handle<JSFunction> result = New<JSFunction>(map, space);
2035 InitializeFunction(result, info, context, maybe_prototype);
2036 return result;
2037 }
2038
2039
2040 Handle<JSFunction> Factory::NewFunction(Handle<String> name,
2041 Handle<Code> code,
2042 MaybeHandle<Object> maybe_prototype) {
2043 Handle<SharedFunctionInfo> info = NewSharedFunctionInfo(name);
2044 info->set_code(*code);
2045 Handle<Context> context(isolate()->context()->native_context());
2046 return NewFunction(info, context, maybe_prototype);
2047 }
2048
2049
2050 Handle<JSFunction> Factory::NewFunctionWithPrototype(Handle<String> name,
2051 Handle<Object> prototype) {
2052 Handle<SharedFunctionInfo> info = NewSharedFunctionInfo(name);
2053 Handle<Context> context(isolate()->context()->native_context());
2054 return NewFunction(info, context, prototype);
2055 }
2056
2057
2058 Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) { 2053 Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) {
2059 // Get the original code of the function. 2054 // Get the original code of the function.
2060 Handle<Code> code(shared->code()); 2055 Handle<Code> code(shared->code());
2061 2056
2062 // Create a copy of the code before allocating the debug info object to avoid 2057 // Create a copy of the code before allocating the debug info object to avoid
2063 // allocation while setting up the debug info object. 2058 // allocation while setting up the debug info object.
2064 Handle<Code> original_code(*Factory::CopyCode(code)); 2059 Handle<Code> original_code(*Factory::CopyCode(code));
2065 2060
2066 // Allocate initial fixed array for active break points before allocating the 2061 // Allocate initial fixed array for active break points before allocating the
2067 // debug info object to avoid allocation while setting up the debug info 2062 // debug info object to avoid allocation while setting up the debug info
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
2349 return Handle<Object>::null(); 2344 return Handle<Object>::null();
2350 } 2345 }
2351 2346
2352 2347
2353 Handle<Object> Factory::ToBoolean(bool value) { 2348 Handle<Object> Factory::ToBoolean(bool value) {
2354 return value ? true_value() : false_value(); 2349 return value ? true_value() : false_value();
2355 } 2350 }
2356 2351
2357 2352
2358 } } // namespace v8::internal 2353 } } // 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