| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #include "v8.h" | 28 #include "v8.h" |
| 29 | 29 |
| 30 #include "api.h" | 30 #include "api.h" |
| 31 #include "arguments.h" | 31 #include "arguments.h" |
| 32 #include "bootstrapper.h" | 32 #include "bootstrapper.h" |
| 33 #include "builtins.h" | 33 #include "builtins.h" |
| 34 #include "gdb-jit.h" |
| 34 #include "ic-inl.h" | 35 #include "ic-inl.h" |
| 35 #include "mark-compact.h" | 36 #include "mark-compact.h" |
| 36 #include "vm-state-inl.h" | 37 #include "vm-state-inl.h" |
| 37 | 38 |
| 38 namespace v8 { | 39 namespace v8 { |
| 39 namespace internal { | 40 namespace internal { |
| 40 | 41 |
| 41 namespace { | 42 namespace { |
| 42 | 43 |
| 43 // Arguments object passed to C++ builtins. | 44 // Arguments object passed to C++ builtins. |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 365 | 366 |
| 366 static bool ArrayPrototypeHasNoElements(Context* global_context, | 367 static bool ArrayPrototypeHasNoElements(Context* global_context, |
| 367 JSObject* array_proto) { | 368 JSObject* array_proto) { |
| 368 // This method depends on non writability of Object and Array prototype | 369 // This method depends on non writability of Object and Array prototype |
| 369 // fields. | 370 // fields. |
| 370 if (array_proto->elements() != Heap::empty_fixed_array()) return false; | 371 if (array_proto->elements() != Heap::empty_fixed_array()) return false; |
| 371 // Hidden prototype | 372 // Hidden prototype |
| 372 array_proto = JSObject::cast(array_proto->GetPrototype()); | 373 array_proto = JSObject::cast(array_proto->GetPrototype()); |
| 373 ASSERT(array_proto->elements() == Heap::empty_fixed_array()); | 374 ASSERT(array_proto->elements() == Heap::empty_fixed_array()); |
| 374 // Object.prototype | 375 // Object.prototype |
| 375 array_proto = JSObject::cast(array_proto->GetPrototype()); | 376 Object* proto = array_proto->GetPrototype(); |
| 377 if (proto == Heap::null_value()) return false; |
| 378 array_proto = JSObject::cast(proto); |
| 376 if (array_proto != global_context->initial_object_prototype()) return false; | 379 if (array_proto != global_context->initial_object_prototype()) return false; |
| 377 if (array_proto->elements() != Heap::empty_fixed_array()) return false; | 380 if (array_proto->elements() != Heap::empty_fixed_array()) return false; |
| 378 ASSERT(array_proto->GetPrototype()->IsNull()); | 381 ASSERT(array_proto->GetPrototype()->IsNull()); |
| 379 return true; | 382 return true; |
| 380 } | 383 } |
| 381 | 384 |
| 382 | 385 |
| 383 MUST_USE_RESULT | 386 MUST_USE_RESULT |
| 384 static inline MaybeObject* EnsureJSArrayWithWritableFastElements( | 387 static inline MaybeObject* EnsureJSArrayWithWritableFastElements( |
| 385 Object* receiver) { | 388 Object* receiver) { |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 634 Top::context()->global_context()->arguments_boilerplate()->map(); | 637 Top::context()->global_context()->arguments_boilerplate()->map(); |
| 635 | 638 |
| 636 bool is_arguments_object_with_fast_elements = | 639 bool is_arguments_object_with_fast_elements = |
| 637 receiver->IsJSObject() | 640 receiver->IsJSObject() |
| 638 && JSObject::cast(receiver)->map() == arguments_map | 641 && JSObject::cast(receiver)->map() == arguments_map |
| 639 && JSObject::cast(receiver)->HasFastElements(); | 642 && JSObject::cast(receiver)->HasFastElements(); |
| 640 if (!is_arguments_object_with_fast_elements) { | 643 if (!is_arguments_object_with_fast_elements) { |
| 641 return CallJsBuiltin("ArraySlice", args); | 644 return CallJsBuiltin("ArraySlice", args); |
| 642 } | 645 } |
| 643 elms = FixedArray::cast(JSObject::cast(receiver)->elements()); | 646 elms = FixedArray::cast(JSObject::cast(receiver)->elements()); |
| 644 len = elms->length(); | 647 Object* len_obj = JSObject::cast(receiver) |
| 645 #ifdef DEBUG | 648 ->InObjectPropertyAt(Heap::arguments_length_index); |
| 646 // Arguments object by construction should have no holes, check it. | 649 if (!len_obj->IsSmi()) { |
| 647 if (FLAG_enable_slow_asserts) { | 650 return CallJsBuiltin("ArraySlice", args); |
| 648 for (int i = 0; i < len; i++) { | 651 } |
| 649 ASSERT(elms->get(i) != Heap::the_hole_value()); | 652 len = Smi::cast(len_obj)->value(); |
| 653 if (len > elms->length()) { |
| 654 return CallJsBuiltin("ArraySlice", args); |
| 655 } |
| 656 for (int i = 0; i < len; i++) { |
| 657 if (elms->get(i) == Heap::the_hole_value()) { |
| 658 return CallJsBuiltin("ArraySlice", args); |
| 650 } | 659 } |
| 651 } | 660 } |
| 652 #endif | |
| 653 } | 661 } |
| 654 ASSERT(len >= 0); | 662 ASSERT(len >= 0); |
| 655 int n_arguments = args.length() - 1; | 663 int n_arguments = args.length() - 1; |
| 656 | 664 |
| 657 // Note carefully choosen defaults---if argument is missing, | 665 // Note carefully choosen defaults---if argument is missing, |
| 658 // it's undefined which gets converted to 0 for relative_start | 666 // it's undefined which gets converted to 0 for relative_start |
| 659 // and to len for relative_end. | 667 // and to len for relative_end. |
| 660 int relative_start = 0; | 668 int relative_start = 0; |
| 661 int relative_end = len; | 669 int relative_end = len; |
| 662 if (n_arguments > 0) { | 670 if (n_arguments > 0) { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 726 return CallJsBuiltin("ArraySplice", args); | 734 return CallJsBuiltin("ArraySplice", args); |
| 727 } | 735 } |
| 728 FixedArray* elms = FixedArray::cast(elms_obj); | 736 FixedArray* elms = FixedArray::cast(elms_obj); |
| 729 JSArray* array = JSArray::cast(receiver); | 737 JSArray* array = JSArray::cast(receiver); |
| 730 ASSERT(array->HasFastElements()); | 738 ASSERT(array->HasFastElements()); |
| 731 | 739 |
| 732 int len = Smi::cast(array->length())->value(); | 740 int len = Smi::cast(array->length())->value(); |
| 733 | 741 |
| 734 int n_arguments = args.length() - 1; | 742 int n_arguments = args.length() - 1; |
| 735 | 743 |
| 736 // Return empty array when no arguments are supplied. | |
| 737 if (n_arguments == 0) { | |
| 738 return AllocateEmptyJSArray(); | |
| 739 } | |
| 740 | |
| 741 int relative_start = 0; | 744 int relative_start = 0; |
| 742 Object* arg1 = args[1]; | 745 if (n_arguments > 0) { |
| 743 if (arg1->IsSmi()) { | 746 Object* arg1 = args[1]; |
| 744 relative_start = Smi::cast(arg1)->value(); | 747 if (arg1->IsSmi()) { |
| 745 } else if (!arg1->IsUndefined()) { | 748 relative_start = Smi::cast(arg1)->value(); |
| 746 return CallJsBuiltin("ArraySplice", args); | 749 } else if (!arg1->IsUndefined()) { |
| 750 return CallJsBuiltin("ArraySplice", args); |
| 751 } |
| 747 } | 752 } |
| 748 int actual_start = (relative_start < 0) ? Max(len + relative_start, 0) | 753 int actual_start = (relative_start < 0) ? Max(len + relative_start, 0) |
| 749 : Min(relative_start, len); | 754 : Min(relative_start, len); |
| 750 | 755 |
| 751 // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is | 756 // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is |
| 752 // given differently from when an undefined delete count is given. | 757 // given as a request to delete all the elements from the start. |
| 758 // And it differs from the case of undefined delete count. |
| 753 // This does not follow ECMA-262, but we do the same for | 759 // This does not follow ECMA-262, but we do the same for |
| 754 // compatibility. | 760 // compatibility. |
| 755 int delete_count = len; | 761 int actual_delete_count; |
| 756 if (n_arguments > 1) { | 762 if (n_arguments == 1) { |
| 757 Object* arg2 = args[2]; | 763 ASSERT(len - actual_start >= 0); |
| 758 if (arg2->IsSmi()) { | 764 actual_delete_count = len - actual_start; |
| 759 delete_count = Smi::cast(arg2)->value(); | 765 } else { |
| 760 } else { | 766 int value = 0; // ToInteger(undefined) == 0 |
| 761 return CallJsBuiltin("ArraySplice", args); | 767 if (n_arguments > 1) { |
| 768 Object* arg2 = args[2]; |
| 769 if (arg2->IsSmi()) { |
| 770 value = Smi::cast(arg2)->value(); |
| 771 } else { |
| 772 return CallJsBuiltin("ArraySplice", args); |
| 773 } |
| 762 } | 774 } |
| 775 actual_delete_count = Min(Max(value, 0), len - actual_start); |
| 763 } | 776 } |
| 764 int actual_delete_count = Min(Max(delete_count, 0), len - actual_start); | |
| 765 | 777 |
| 766 JSArray* result_array = NULL; | 778 JSArray* result_array = NULL; |
| 767 if (actual_delete_count == 0) { | 779 if (actual_delete_count == 0) { |
| 768 Object* result; | 780 Object* result; |
| 769 { MaybeObject* maybe_result = AllocateEmptyJSArray(); | 781 { MaybeObject* maybe_result = AllocateEmptyJSArray(); |
| 770 if (!maybe_result->ToObject(&result)) return maybe_result; | 782 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 771 } | 783 } |
| 772 result_array = JSArray::cast(result); | 784 result_array = JSArray::cast(result); |
| 773 } else { | 785 } else { |
| 774 // Allocate result array. | 786 // Allocate result array. |
| (...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1220 return HandleApiCallAsFunctionOrConstructor(true, args); | 1232 return HandleApiCallAsFunctionOrConstructor(true, args); |
| 1221 } | 1233 } |
| 1222 | 1234 |
| 1223 | 1235 |
| 1224 static void Generate_LoadIC_ArrayLength(MacroAssembler* masm) { | 1236 static void Generate_LoadIC_ArrayLength(MacroAssembler* masm) { |
| 1225 LoadIC::GenerateArrayLength(masm); | 1237 LoadIC::GenerateArrayLength(masm); |
| 1226 } | 1238 } |
| 1227 | 1239 |
| 1228 | 1240 |
| 1229 static void Generate_LoadIC_StringLength(MacroAssembler* masm) { | 1241 static void Generate_LoadIC_StringLength(MacroAssembler* masm) { |
| 1230 LoadIC::GenerateStringLength(masm); | 1242 LoadIC::GenerateStringLength(masm, false); |
| 1243 } |
| 1244 |
| 1245 |
| 1246 static void Generate_LoadIC_StringWrapperLength(MacroAssembler* masm) { |
| 1247 LoadIC::GenerateStringLength(masm, true); |
| 1231 } | 1248 } |
| 1232 | 1249 |
| 1233 | 1250 |
| 1234 static void Generate_LoadIC_FunctionPrototype(MacroAssembler* masm) { | 1251 static void Generate_LoadIC_FunctionPrototype(MacroAssembler* masm) { |
| 1235 LoadIC::GenerateFunctionPrototype(masm); | 1252 LoadIC::GenerateFunctionPrototype(masm); |
| 1236 } | 1253 } |
| 1237 | 1254 |
| 1238 | 1255 |
| 1239 static void Generate_LoadIC_Initialize(MacroAssembler* masm) { | 1256 static void Generate_LoadIC_Initialize(MacroAssembler* masm) { |
| 1240 LoadIC::GenerateInitialize(masm); | 1257 LoadIC::GenerateInitialize(masm); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1274 static void Generate_KeyedLoadIC_Generic(MacroAssembler* masm) { | 1291 static void Generate_KeyedLoadIC_Generic(MacroAssembler* masm) { |
| 1275 KeyedLoadIC::GenerateGeneric(masm); | 1292 KeyedLoadIC::GenerateGeneric(masm); |
| 1276 } | 1293 } |
| 1277 | 1294 |
| 1278 | 1295 |
| 1279 static void Generate_KeyedLoadIC_String(MacroAssembler* masm) { | 1296 static void Generate_KeyedLoadIC_String(MacroAssembler* masm) { |
| 1280 KeyedLoadIC::GenerateString(masm); | 1297 KeyedLoadIC::GenerateString(masm); |
| 1281 } | 1298 } |
| 1282 | 1299 |
| 1283 | 1300 |
| 1284 static void Generate_KeyedLoadIC_ExternalByteArray(MacroAssembler* masm) { | |
| 1285 KeyedLoadIC::GenerateExternalArray(masm, kExternalByteArray); | |
| 1286 } | |
| 1287 | |
| 1288 | |
| 1289 static void Generate_KeyedLoadIC_ExternalUnsignedByteArray( | |
| 1290 MacroAssembler* masm) { | |
| 1291 KeyedLoadIC::GenerateExternalArray(masm, kExternalUnsignedByteArray); | |
| 1292 } | |
| 1293 | |
| 1294 | |
| 1295 static void Generate_KeyedLoadIC_ExternalShortArray(MacroAssembler* masm) { | |
| 1296 KeyedLoadIC::GenerateExternalArray(masm, kExternalShortArray); | |
| 1297 } | |
| 1298 | |
| 1299 | |
| 1300 static void Generate_KeyedLoadIC_ExternalUnsignedShortArray( | |
| 1301 MacroAssembler* masm) { | |
| 1302 KeyedLoadIC::GenerateExternalArray(masm, kExternalUnsignedShortArray); | |
| 1303 } | |
| 1304 | |
| 1305 | |
| 1306 static void Generate_KeyedLoadIC_ExternalIntArray(MacroAssembler* masm) { | |
| 1307 KeyedLoadIC::GenerateExternalArray(masm, kExternalIntArray); | |
| 1308 } | |
| 1309 | |
| 1310 | |
| 1311 static void Generate_KeyedLoadIC_ExternalUnsignedIntArray( | |
| 1312 MacroAssembler* masm) { | |
| 1313 KeyedLoadIC::GenerateExternalArray(masm, kExternalUnsignedIntArray); | |
| 1314 } | |
| 1315 | |
| 1316 | |
| 1317 static void Generate_KeyedLoadIC_ExternalFloatArray(MacroAssembler* masm) { | |
| 1318 KeyedLoadIC::GenerateExternalArray(masm, kExternalFloatArray); | |
| 1319 } | |
| 1320 | |
| 1321 | |
| 1322 static void Generate_KeyedLoadIC_PreMonomorphic(MacroAssembler* masm) { | 1301 static void Generate_KeyedLoadIC_PreMonomorphic(MacroAssembler* masm) { |
| 1323 KeyedLoadIC::GeneratePreMonomorphic(masm); | 1302 KeyedLoadIC::GeneratePreMonomorphic(masm); |
| 1324 } | 1303 } |
| 1325 | 1304 |
| 1326 static void Generate_KeyedLoadIC_IndexedInterceptor(MacroAssembler* masm) { | 1305 static void Generate_KeyedLoadIC_IndexedInterceptor(MacroAssembler* masm) { |
| 1327 KeyedLoadIC::GenerateIndexedInterceptor(masm); | 1306 KeyedLoadIC::GenerateIndexedInterceptor(masm); |
| 1328 } | 1307 } |
| 1329 | 1308 |
| 1330 | 1309 |
| 1331 static void Generate_StoreIC_Initialize(MacroAssembler* masm) { | 1310 static void Generate_StoreIC_Initialize(MacroAssembler* masm) { |
| 1332 StoreIC::GenerateInitialize(masm); | 1311 StoreIC::GenerateInitialize(masm); |
| 1333 } | 1312 } |
| 1334 | 1313 |
| 1335 | 1314 |
| 1315 static void Generate_StoreIC_Initialize_Strict(MacroAssembler* masm) { |
| 1316 StoreIC::GenerateInitialize(masm); |
| 1317 } |
| 1318 |
| 1319 |
| 1336 static void Generate_StoreIC_Miss(MacroAssembler* masm) { | 1320 static void Generate_StoreIC_Miss(MacroAssembler* masm) { |
| 1337 StoreIC::GenerateMiss(masm); | 1321 StoreIC::GenerateMiss(masm); |
| 1338 } | 1322 } |
| 1339 | 1323 |
| 1340 | 1324 |
| 1341 static void Generate_StoreIC_Normal(MacroAssembler* masm) { | 1325 static void Generate_StoreIC_Normal(MacroAssembler* masm) { |
| 1342 StoreIC::GenerateNormal(masm); | 1326 StoreIC::GenerateNormal(masm); |
| 1343 } | 1327 } |
| 1344 | 1328 |
| 1345 | 1329 |
| 1330 static void Generate_StoreIC_Normal_Strict(MacroAssembler* masm) { |
| 1331 StoreIC::GenerateNormal(masm); |
| 1332 } |
| 1333 |
| 1334 |
| 1346 static void Generate_StoreIC_Megamorphic(MacroAssembler* masm) { | 1335 static void Generate_StoreIC_Megamorphic(MacroAssembler* masm) { |
| 1347 StoreIC::GenerateMegamorphic(masm); | 1336 StoreIC::GenerateMegamorphic(masm, StoreIC::kStoreICNonStrict); |
| 1337 } |
| 1338 |
| 1339 |
| 1340 static void Generate_StoreIC_Megamorphic_Strict(MacroAssembler* masm) { |
| 1341 StoreIC::GenerateMegamorphic(masm, StoreIC::kStoreICStrict); |
| 1348 } | 1342 } |
| 1349 | 1343 |
| 1350 | 1344 |
| 1351 static void Generate_StoreIC_ArrayLength(MacroAssembler* masm) { | 1345 static void Generate_StoreIC_ArrayLength(MacroAssembler* masm) { |
| 1352 StoreIC::GenerateArrayLength(masm); | 1346 StoreIC::GenerateArrayLength(masm); |
| 1353 } | 1347 } |
| 1354 | 1348 |
| 1355 | 1349 |
| 1350 static void Generate_StoreIC_ArrayLength_Strict(MacroAssembler* masm) { |
| 1351 StoreIC::GenerateArrayLength(masm); |
| 1352 } |
| 1353 |
| 1354 |
| 1356 static void Generate_StoreIC_GlobalProxy(MacroAssembler* masm) { | 1355 static void Generate_StoreIC_GlobalProxy(MacroAssembler* masm) { |
| 1357 StoreIC::GenerateGlobalProxy(masm); | 1356 StoreIC::GenerateGlobalProxy(masm); |
| 1358 } | 1357 } |
| 1359 | 1358 |
| 1360 | 1359 |
| 1361 static void Generate_KeyedStoreIC_Generic(MacroAssembler* masm) { | 1360 static void Generate_StoreIC_GlobalProxy_Strict(MacroAssembler* masm) { |
| 1362 KeyedStoreIC::GenerateGeneric(masm); | 1361 StoreIC::GenerateGlobalProxy(masm); |
| 1363 } | 1362 } |
| 1364 | 1363 |
| 1365 | 1364 |
| 1366 static void Generate_KeyedStoreIC_ExternalByteArray(MacroAssembler* masm) { | 1365 static void Generate_KeyedStoreIC_Generic(MacroAssembler* masm) { |
| 1367 KeyedStoreIC::GenerateExternalArray(masm, kExternalByteArray); | 1366 KeyedStoreIC::GenerateGeneric(masm); |
| 1368 } | |
| 1369 | |
| 1370 | |
| 1371 static void Generate_KeyedStoreIC_ExternalUnsignedByteArray( | |
| 1372 MacroAssembler* masm) { | |
| 1373 KeyedStoreIC::GenerateExternalArray(masm, kExternalUnsignedByteArray); | |
| 1374 } | |
| 1375 | |
| 1376 | |
| 1377 static void Generate_KeyedStoreIC_ExternalShortArray(MacroAssembler* masm) { | |
| 1378 KeyedStoreIC::GenerateExternalArray(masm, kExternalShortArray); | |
| 1379 } | |
| 1380 | |
| 1381 | |
| 1382 static void Generate_KeyedStoreIC_ExternalUnsignedShortArray( | |
| 1383 MacroAssembler* masm) { | |
| 1384 KeyedStoreIC::GenerateExternalArray(masm, kExternalUnsignedShortArray); | |
| 1385 } | |
| 1386 | |
| 1387 | |
| 1388 static void Generate_KeyedStoreIC_ExternalIntArray(MacroAssembler* masm) { | |
| 1389 KeyedStoreIC::GenerateExternalArray(masm, kExternalIntArray); | |
| 1390 } | |
| 1391 | |
| 1392 | |
| 1393 static void Generate_KeyedStoreIC_ExternalUnsignedIntArray( | |
| 1394 MacroAssembler* masm) { | |
| 1395 KeyedStoreIC::GenerateExternalArray(masm, kExternalUnsignedIntArray); | |
| 1396 } | |
| 1397 | |
| 1398 | |
| 1399 static void Generate_KeyedStoreIC_ExternalFloatArray(MacroAssembler* masm) { | |
| 1400 KeyedStoreIC::GenerateExternalArray(masm, kExternalFloatArray); | |
| 1401 } | 1367 } |
| 1402 | 1368 |
| 1403 | 1369 |
| 1404 static void Generate_KeyedStoreIC_Miss(MacroAssembler* masm) { | 1370 static void Generate_KeyedStoreIC_Miss(MacroAssembler* masm) { |
| 1405 KeyedStoreIC::GenerateMiss(masm); | 1371 KeyedStoreIC::GenerateMiss(masm); |
| 1406 } | 1372 } |
| 1407 | 1373 |
| 1408 | 1374 |
| 1409 static void Generate_KeyedStoreIC_Initialize(MacroAssembler* masm) { | 1375 static void Generate_KeyedStoreIC_Initialize(MacroAssembler* masm) { |
| 1410 KeyedStoreIC::GenerateInitialize(masm); | 1376 KeyedStoreIC::GenerateInitialize(masm); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1501 | 1467 |
| 1502 #define DEF_FUNCTION_PTR_C(name, extra_args) \ | 1468 #define DEF_FUNCTION_PTR_C(name, extra_args) \ |
| 1503 { FUNCTION_ADDR(Generate_Adaptor), \ | 1469 { FUNCTION_ADDR(Generate_Adaptor), \ |
| 1504 FUNCTION_ADDR(Builtin_##name), \ | 1470 FUNCTION_ADDR(Builtin_##name), \ |
| 1505 #name, \ | 1471 #name, \ |
| 1506 c_##name, \ | 1472 c_##name, \ |
| 1507 Code::ComputeFlags(Code::BUILTIN), \ | 1473 Code::ComputeFlags(Code::BUILTIN), \ |
| 1508 extra_args \ | 1474 extra_args \ |
| 1509 }, | 1475 }, |
| 1510 | 1476 |
| 1511 #define DEF_FUNCTION_PTR_A(name, kind, state) \ | 1477 #define DEF_FUNCTION_PTR_A(name, kind, state, extra) \ |
| 1512 { FUNCTION_ADDR(Generate_##name), \ | 1478 { FUNCTION_ADDR(Generate_##name), \ |
| 1513 NULL, \ | 1479 NULL, \ |
| 1514 #name, \ | 1480 #name, \ |
| 1515 name, \ | 1481 name, \ |
| 1516 Code::ComputeFlags(Code::kind, NOT_IN_LOOP, state), \ | 1482 Code::ComputeFlags(Code::kind, NOT_IN_LOOP, state, extra), \ |
| 1517 NO_EXTRA_ARGUMENTS \ | 1483 NO_EXTRA_ARGUMENTS \ |
| 1518 }, | 1484 }, |
| 1519 | 1485 |
| 1520 // Define array of pointers to generators and C builtin functions. | 1486 // Define array of pointers to generators and C builtin functions. |
| 1521 static BuiltinDesc functions[] = { | 1487 static BuiltinDesc functions[] = { |
| 1522 BUILTIN_LIST_C(DEF_FUNCTION_PTR_C) | 1488 BUILTIN_LIST_C(DEF_FUNCTION_PTR_C) |
| 1523 BUILTIN_LIST_A(DEF_FUNCTION_PTR_A) | 1489 BUILTIN_LIST_A(DEF_FUNCTION_PTR_A) |
| 1524 BUILTIN_LIST_DEBUG_A(DEF_FUNCTION_PTR_A) | 1490 BUILTIN_LIST_DEBUG_A(DEF_FUNCTION_PTR_A) |
| 1525 // Terminator: | 1491 // Terminator: |
| 1526 { NULL, NULL, NULL, builtin_count, static_cast<Code::Flags>(0), | 1492 { NULL, NULL, NULL, builtin_count, static_cast<Code::Flags>(0), |
| 1527 NO_EXTRA_ARGUMENTS } | 1493 NO_EXTRA_ARGUMENTS } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1543 typedef void (*Generator)(MacroAssembler*, int, BuiltinExtraArguments); | 1509 typedef void (*Generator)(MacroAssembler*, int, BuiltinExtraArguments); |
| 1544 Generator g = FUNCTION_CAST<Generator>(functions[i].generator); | 1510 Generator g = FUNCTION_CAST<Generator>(functions[i].generator); |
| 1545 // We pass all arguments to the generator, but it may not use all of | 1511 // We pass all arguments to the generator, but it may not use all of |
| 1546 // them. This works because the first arguments are on top of the | 1512 // them. This works because the first arguments are on top of the |
| 1547 // stack. | 1513 // stack. |
| 1548 g(&masm, functions[i].name, functions[i].extra_args); | 1514 g(&masm, functions[i].name, functions[i].extra_args); |
| 1549 // Move the code into the object heap. | 1515 // Move the code into the object heap. |
| 1550 CodeDesc desc; | 1516 CodeDesc desc; |
| 1551 masm.GetCode(&desc); | 1517 masm.GetCode(&desc); |
| 1552 Code::Flags flags = functions[i].flags; | 1518 Code::Flags flags = functions[i].flags; |
| 1553 Object* code = 0; | 1519 Object* code = NULL; |
| 1554 { | 1520 { |
| 1555 // During startup it's OK to always allocate and defer GC to later. | 1521 // During startup it's OK to always allocate and defer GC to later. |
| 1556 // This simplifies things because we don't need to retry. | 1522 // This simplifies things because we don't need to retry. |
| 1557 AlwaysAllocateScope __scope__; | 1523 AlwaysAllocateScope __scope__; |
| 1558 { MaybeObject* maybe_code = | 1524 { MaybeObject* maybe_code = |
| 1559 Heap::CreateCode(desc, flags, masm.CodeObject()); | 1525 Heap::CreateCode(desc, flags, masm.CodeObject()); |
| 1560 if (!maybe_code->ToObject(&code)) { | 1526 if (!maybe_code->ToObject(&code)) { |
| 1561 v8::internal::V8::FatalProcessOutOfMemory("CreateCode"); | 1527 v8::internal::V8::FatalProcessOutOfMemory("CreateCode"); |
| 1562 } | 1528 } |
| 1563 } | 1529 } |
| 1564 } | 1530 } |
| 1565 // Log the event and add the code to the builtins array. | 1531 // Log the event and add the code to the builtins array. |
| 1566 PROFILE(CodeCreateEvent(Logger::BUILTIN_TAG, | 1532 PROFILE(CodeCreateEvent(Logger::BUILTIN_TAG, |
| 1567 Code::cast(code), functions[i].s_name)); | 1533 Code::cast(code), |
| 1534 functions[i].s_name)); |
| 1535 GDBJIT(AddCode(GDBJITInterface::BUILTIN, |
| 1536 functions[i].s_name, |
| 1537 Code::cast(code))); |
| 1568 builtins_[i] = code; | 1538 builtins_[i] = code; |
| 1569 #ifdef ENABLE_DISASSEMBLER | 1539 #ifdef ENABLE_DISASSEMBLER |
| 1570 if (FLAG_print_builtin_code) { | 1540 if (FLAG_print_builtin_code) { |
| 1571 PrintF("Builtin: %s\n", functions[i].s_name); | 1541 PrintF("Builtin: %s\n", functions[i].s_name); |
| 1572 Code::cast(code)->Disassemble(functions[i].s_name); | 1542 Code::cast(code)->Disassemble(functions[i].s_name); |
| 1573 PrintF("\n"); | 1543 PrintF("\n"); |
| 1574 } | 1544 } |
| 1575 #endif | 1545 #endif |
| 1576 } else { | 1546 } else { |
| 1577 // Deserializing. The values will be filled in during IterateBuiltins. | 1547 // Deserializing. The values will be filled in during IterateBuiltins. |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1602 if (entry->contains(pc)) { | 1572 if (entry->contains(pc)) { |
| 1603 return names_[i]; | 1573 return names_[i]; |
| 1604 } | 1574 } |
| 1605 } | 1575 } |
| 1606 } | 1576 } |
| 1607 return NULL; | 1577 return NULL; |
| 1608 } | 1578 } |
| 1609 | 1579 |
| 1610 | 1580 |
| 1611 } } // namespace v8::internal | 1581 } } // namespace v8::internal |
| OLD | NEW |