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 1359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1370 static void Generate_PlainReturn_LiveEdit(MacroAssembler* masm) { | 1370 static void Generate_PlainReturn_LiveEdit(MacroAssembler* masm) { |
1371 Debug::GeneratePlainReturnLiveEdit(masm); | 1371 Debug::GeneratePlainReturnLiveEdit(masm); |
1372 } | 1372 } |
1373 | 1373 |
1374 | 1374 |
1375 static void Generate_FrameDropper_LiveEdit(MacroAssembler* masm) { | 1375 static void Generate_FrameDropper_LiveEdit(MacroAssembler* masm) { |
1376 Debug::GenerateFrameDropperLiveEdit(masm); | 1376 Debug::GenerateFrameDropperLiveEdit(masm); |
1377 } | 1377 } |
1378 #endif | 1378 #endif |
1379 | 1379 |
1380 Object* Builtins::builtins_[builtin_count] = { NULL, }; | 1380 |
1381 const char* Builtins::names_[builtin_count] = { NULL, }; | 1381 Builtins::Builtins() { |
| 1382 memset(builtins_, 0, sizeof(builtins_[0]) * builtin_count); |
| 1383 memset(names_, 0, sizeof(names_[0]) * builtin_count); |
| 1384 } |
| 1385 |
| 1386 |
| 1387 Builtins::~Builtins() { |
| 1388 } |
| 1389 |
1382 | 1390 |
1383 #define DEF_ENUM_C(name, ignore) FUNCTION_ADDR(Builtin_##name), | 1391 #define DEF_ENUM_C(name, ignore) FUNCTION_ADDR(Builtin_##name), |
1384 Address Builtins::c_functions_[cfunction_count] = { | 1392 Address const Builtins::c_functions_[cfunction_count] = { |
1385 BUILTIN_LIST_C(DEF_ENUM_C) | 1393 BUILTIN_LIST_C(DEF_ENUM_C) |
1386 }; | 1394 }; |
1387 #undef DEF_ENUM_C | 1395 #undef DEF_ENUM_C |
1388 | 1396 |
1389 #define DEF_JS_NAME(name, ignore) #name, | 1397 #define DEF_JS_NAME(name, ignore) #name, |
1390 #define DEF_JS_ARGC(ignore, argc) argc, | 1398 #define DEF_JS_ARGC(ignore, argc) argc, |
1391 const char* Builtins::javascript_names_[id_count] = { | 1399 const char* const Builtins::javascript_names_[id_count] = { |
1392 BUILTINS_LIST_JS(DEF_JS_NAME) | 1400 BUILTINS_LIST_JS(DEF_JS_NAME) |
1393 }; | 1401 }; |
1394 | 1402 |
1395 int Builtins::javascript_argc_[id_count] = { | 1403 int const Builtins::javascript_argc_[id_count] = { |
1396 BUILTINS_LIST_JS(DEF_JS_ARGC) | 1404 BUILTINS_LIST_JS(DEF_JS_ARGC) |
1397 }; | 1405 }; |
1398 #undef DEF_JS_NAME | 1406 #undef DEF_JS_NAME |
1399 #undef DEF_JS_ARGC | 1407 #undef DEF_JS_ARGC |
1400 | 1408 |
1401 static bool is_initialized = false; | 1409 struct BuiltinDesc { |
| 1410 byte* generator; |
| 1411 byte* c_code; |
| 1412 const char* s_name; // name is only used for generating log information. |
| 1413 int name; |
| 1414 Code::Flags flags; |
| 1415 BuiltinExtraArguments extra_args; |
| 1416 }; |
| 1417 |
| 1418 class BuiltinFunctionTable { |
| 1419 public: |
| 1420 BuiltinFunctionTable() { |
| 1421 Builtins::InitBuiltinFunctionTable(); |
| 1422 } |
| 1423 |
| 1424 static const BuiltinDesc* functions() { return functions_; } |
| 1425 |
| 1426 private: |
| 1427 static BuiltinDesc functions_[Builtins::builtin_count + 1]; |
| 1428 |
| 1429 friend class Builtins; |
| 1430 }; |
| 1431 |
| 1432 BuiltinDesc BuiltinFunctionTable::functions_[Builtins::builtin_count + 1]; |
| 1433 |
| 1434 static const BuiltinFunctionTable builtin_function_table_init; |
| 1435 |
| 1436 // Define array of pointers to generators and C builtin functions. |
| 1437 // We do this in a sort of roundabout way so that we can do the initialization |
| 1438 // within the lexical scope of Builtins:: and within a context where |
| 1439 // Code::Flags names a non-abstract type. |
| 1440 void Builtins::InitBuiltinFunctionTable() { |
| 1441 BuiltinDesc* functions = BuiltinFunctionTable::functions_; |
| 1442 functions[builtin_count].generator = NULL; |
| 1443 functions[builtin_count].c_code = NULL; |
| 1444 functions[builtin_count].s_name = NULL; |
| 1445 functions[builtin_count].name = builtin_count; |
| 1446 functions[builtin_count].flags = static_cast<Code::Flags>(0); |
| 1447 functions[builtin_count].extra_args = NO_EXTRA_ARGUMENTS; |
| 1448 |
| 1449 #define DEF_FUNCTION_PTR_C(aname, aextra_args) \ |
| 1450 functions->generator = FUNCTION_ADDR(Generate_Adaptor); \ |
| 1451 functions->c_code = FUNCTION_ADDR(Builtin_##aname); \ |
| 1452 functions->s_name = #aname; \ |
| 1453 functions->name = c_##aname; \ |
| 1454 functions->flags = Code::ComputeFlags(Code::BUILTIN); \ |
| 1455 functions->extra_args = aextra_args; \ |
| 1456 ++functions; |
| 1457 |
| 1458 #define DEF_FUNCTION_PTR_A(aname, kind, state) \ |
| 1459 functions->generator = FUNCTION_ADDR(Generate_##aname); \ |
| 1460 functions->c_code = NULL; \ |
| 1461 functions->s_name = #aname; \ |
| 1462 functions->name = aname; \ |
| 1463 functions->flags = Code::ComputeFlags(Code::kind, NOT_IN_LOOP, state); \ |
| 1464 functions->extra_args = NO_EXTRA_ARGUMENTS; \ |
| 1465 ++functions; |
| 1466 |
| 1467 BUILTIN_LIST_C(DEF_FUNCTION_PTR_C) |
| 1468 BUILTIN_LIST_A(DEF_FUNCTION_PTR_A) |
| 1469 BUILTIN_LIST_DEBUG_A(DEF_FUNCTION_PTR_A) |
| 1470 |
| 1471 #undef DEF_FUNCTION_PTR_C |
| 1472 #undef DEF_FUNCTION_PTR_A |
| 1473 } |
| 1474 |
1402 void Builtins::Setup(bool create_heap_objects) { | 1475 void Builtins::Setup(bool create_heap_objects) { |
1403 ASSERT(!is_initialized); | 1476 ASSERT(!initialized_); |
1404 | 1477 |
1405 // Create a scope for the handles in the builtins. | 1478 // Create a scope for the handles in the builtins. |
1406 HandleScope scope; | 1479 HandleScope scope; |
1407 | 1480 |
1408 struct BuiltinDesc { | 1481 const BuiltinDesc* functions = BuiltinFunctionTable::functions(); |
1409 byte* generator; | |
1410 byte* c_code; | |
1411 const char* s_name; // name is only used for generating log information. | |
1412 int name; | |
1413 Code::Flags flags; | |
1414 BuiltinExtraArguments extra_args; | |
1415 }; | |
1416 | |
1417 #define DEF_FUNCTION_PTR_C(name, extra_args) \ | |
1418 { FUNCTION_ADDR(Generate_Adaptor), \ | |
1419 FUNCTION_ADDR(Builtin_##name), \ | |
1420 #name, \ | |
1421 c_##name, \ | |
1422 Code::ComputeFlags(Code::BUILTIN), \ | |
1423 extra_args \ | |
1424 }, | |
1425 | |
1426 #define DEF_FUNCTION_PTR_A(name, kind, state) \ | |
1427 { FUNCTION_ADDR(Generate_##name), \ | |
1428 NULL, \ | |
1429 #name, \ | |
1430 name, \ | |
1431 Code::ComputeFlags(Code::kind, NOT_IN_LOOP, state), \ | |
1432 NO_EXTRA_ARGUMENTS \ | |
1433 }, | |
1434 | |
1435 // Define array of pointers to generators and C builtin functions. | |
1436 static BuiltinDesc functions[] = { | |
1437 BUILTIN_LIST_C(DEF_FUNCTION_PTR_C) | |
1438 BUILTIN_LIST_A(DEF_FUNCTION_PTR_A) | |
1439 BUILTIN_LIST_DEBUG_A(DEF_FUNCTION_PTR_A) | |
1440 // Terminator: | |
1441 { NULL, NULL, NULL, builtin_count, static_cast<Code::Flags>(0), | |
1442 NO_EXTRA_ARGUMENTS } | |
1443 }; | |
1444 | |
1445 #undef DEF_FUNCTION_PTR_C | |
1446 #undef DEF_FUNCTION_PTR_A | |
1447 | 1482 |
1448 // For now we generate builtin adaptor code into a stack-allocated | 1483 // For now we generate builtin adaptor code into a stack-allocated |
1449 // buffer, before copying it into individual code objects. | 1484 // buffer, before copying it into individual code objects. |
1450 byte buffer[4*KB]; | 1485 byte buffer[4*KB]; |
1451 | 1486 |
1452 // Traverse the list of builtins and generate an adaptor in a | 1487 // Traverse the list of builtins and generate an adaptor in a |
1453 // separate code object for each one. | 1488 // separate code object for each one. |
1454 for (int i = 0; i < builtin_count; i++) { | 1489 for (int i = 0; i < builtin_count; i++) { |
1455 if (create_heap_objects) { | 1490 if (create_heap_objects) { |
1456 MacroAssembler masm(buffer, sizeof buffer); | 1491 MacroAssembler masm(buffer, sizeof buffer); |
(...skipping 30 matching lines...) Expand all Loading... |
1487 } | 1522 } |
1488 #endif | 1523 #endif |
1489 } else { | 1524 } else { |
1490 // Deserializing. The values will be filled in during IterateBuiltins. | 1525 // Deserializing. The values will be filled in during IterateBuiltins. |
1491 builtins_[i] = NULL; | 1526 builtins_[i] = NULL; |
1492 } | 1527 } |
1493 names_[i] = functions[i].s_name; | 1528 names_[i] = functions[i].s_name; |
1494 } | 1529 } |
1495 | 1530 |
1496 // Mark as initialized. | 1531 // Mark as initialized. |
1497 is_initialized = true; | 1532 initialized_ = true; |
1498 } | 1533 } |
1499 | 1534 |
1500 | 1535 |
1501 void Builtins::TearDown() { | 1536 void Builtins::TearDown() { |
1502 is_initialized = false; | 1537 initialized_ = false; |
1503 } | 1538 } |
1504 | 1539 |
1505 | 1540 |
1506 void Builtins::IterateBuiltins(ObjectVisitor* v) { | 1541 void Builtins::IterateBuiltins(ObjectVisitor* v) { |
1507 v->VisitPointers(&builtins_[0], &builtins_[0] + builtin_count); | 1542 v->VisitPointers(&builtins_[0], &builtins_[0] + builtin_count); |
1508 } | 1543 } |
1509 | 1544 |
1510 | 1545 |
1511 const char* Builtins::Lookup(byte* pc) { | 1546 const char* Builtins::Lookup(byte* pc) { |
1512 if (is_initialized) { // may be called during initialization (disassembler!) | 1547 // may be called during initialization (disassembler!) |
| 1548 if (initialized_) { |
1513 for (int i = 0; i < builtin_count; i++) { | 1549 for (int i = 0; i < builtin_count; i++) { |
1514 Code* entry = Code::cast(builtins_[i]); | 1550 Code* entry = Code::cast(builtins_[i]); |
1515 if (entry->contains(pc)) { | 1551 if (entry->contains(pc)) { |
1516 return names_[i]; | 1552 return names_[i]; |
1517 } | 1553 } |
1518 } | 1554 } |
1519 } | 1555 } |
1520 return NULL; | 1556 return NULL; |
1521 } | 1557 } |
1522 | 1558 |
1523 | 1559 |
1524 } } // namespace v8::internal | 1560 } } // namespace v8::internal |
OLD | NEW |