| 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 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 | 410 |
| 411 uint32_t code(int i) { return refs_[i].code; } | 411 uint32_t code(int i) { return refs_[i].code; } |
| 412 | 412 |
| 413 const char* name(int i) { return refs_[i].name; } | 413 const char* name(int i) { return refs_[i].name; } |
| 414 | 414 |
| 415 int max_id(int code) { return max_id_[code]; } | 415 int max_id(int code) { return max_id_[code]; } |
| 416 | 416 |
| 417 private: | 417 private: |
| 418 static ExternalReferenceTable* instance_; | 418 static ExternalReferenceTable* instance_; |
| 419 | 419 |
| 420 ExternalReferenceTable(); | 420 ExternalReferenceTable() : refs_(64) { PopulateTable(); } |
| 421 ~ExternalReferenceTable() { } |
| 421 | 422 |
| 422 struct ExternalReferenceEntry { | 423 struct ExternalReferenceEntry { |
| 423 Address address; | 424 Address address; |
| 424 uint32_t code; | 425 uint32_t code; |
| 425 const char* name; | 426 const char* name; |
| 426 }; | 427 }; |
| 427 | 428 |
| 428 void Add(Address address, TypeCode type, uint16_t id, const char* name) { | 429 void PopulateTable(); |
| 429 CHECK_NE(NULL, address); | 430 |
| 430 ExternalReferenceEntry entry; | 431 // For a few types of references, we can get their address from their id. |
| 431 entry.address = address; | 432 void AddFromId(TypeCode type, uint16_t id, const char* name); |
| 432 entry.code = EncodeExternal(type, id); | 433 |
| 433 entry.name = name; | 434 // For other types of references, the caller will figure out the address. |
| 434 CHECK_NE(0, entry.code); | 435 void Add(Address address, TypeCode type, uint16_t id, const char* name); |
| 435 refs_.Add(entry); | |
| 436 if (id > max_id_[type]) max_id_[type] = id; | |
| 437 } | |
| 438 | 436 |
| 439 List<ExternalReferenceEntry> refs_; | 437 List<ExternalReferenceEntry> refs_; |
| 440 int max_id_[kTypeCodeCount]; | 438 int max_id_[kTypeCodeCount]; |
| 441 }; | 439 }; |
| 442 | 440 |
| 443 | 441 |
| 444 ExternalReferenceTable* ExternalReferenceTable::instance_ = NULL; | 442 ExternalReferenceTable* ExternalReferenceTable::instance_ = NULL; |
| 445 | 443 |
| 444 void ExternalReferenceTable::AddFromId(TypeCode type, |
| 445 uint16_t id, |
| 446 const char* name) { |
| 447 Address address; |
| 448 switch (type) { |
| 449 case C_BUILTIN: |
| 450 address = Builtins::c_function_address( |
| 451 static_cast<Builtins::CFunctionId>(id)); |
| 452 break; |
| 453 case BUILTIN: |
| 454 address = Builtins::builtin_address(static_cast<Builtins::Name>(id)); |
| 455 break; |
| 456 case RUNTIME_FUNCTION: |
| 457 address = Runtime::FunctionForId( |
| 458 static_cast<Runtime::FunctionId>(id))->entry; |
| 459 break; |
| 460 case IC_UTILITY: |
| 461 address = IC::AddressFromUtilityId(static_cast<IC::UtilityId>(id)); |
| 462 break; |
| 463 default: |
| 464 UNREACHABLE(); |
| 465 return; |
| 466 } |
| 467 Add(address, type, id, name); |
| 468 } |
| 446 | 469 |
| 447 ExternalReferenceTable::ExternalReferenceTable() : refs_(64) { | 470 void ExternalReferenceTable::Add(Address address, |
| 471 TypeCode type, |
| 472 uint16_t id, |
| 473 const char* name) { |
| 474 CHECK_NE(NULL, address); |
| 475 ExternalReferenceEntry entry; |
| 476 entry.address = address; |
| 477 entry.code = EncodeExternal(type, id); |
| 478 entry.name = name; |
| 479 CHECK_NE(0, entry.code); |
| 480 refs_.Add(entry); |
| 481 if (id > max_id_[type]) max_id_[type] = id; |
| 482 } |
| 483 |
| 484 |
| 485 void ExternalReferenceTable::PopulateTable() { |
| 448 for (int type_code = 0; type_code < kTypeCodeCount; type_code++) { | 486 for (int type_code = 0; type_code < kTypeCodeCount; type_code++) { |
| 449 max_id_[type_code] = 0; | 487 max_id_[type_code] = 0; |
| 450 } | 488 } |
| 451 | 489 |
| 452 // Define all entries in the table. | 490 // The following populates all of the different type of external references |
| 491 // into the ExternalReferenceTable. |
| 492 // |
| 493 // NOTE: This function was originally 100k of code. It has since been |
| 494 // rewritten to be mostly table driven, as the callback macro style tends to |
| 495 // very easily cause code bloat. Please be careful in the future when adding |
| 496 // new references. |
| 453 | 497 |
| 498 struct RefTableEntry { |
| 499 TypeCode type; |
| 500 uint16_t id; |
| 501 const char* name; |
| 502 }; |
| 503 |
| 504 static const RefTableEntry ref_table[] = { |
| 454 // Builtins | 505 // Builtins |
| 455 #define DEF_ENTRY_C(name) \ | 506 #define DEF_ENTRY_C(name) \ |
| 456 Add(Builtins::c_function_address(Builtins::c_##name), \ | 507 { C_BUILTIN, \ |
| 457 C_BUILTIN, \ | 508 Builtins::c_##name, \ |
| 458 Builtins::c_##name, \ | 509 "Builtins::" #name }, |
| 459 "Builtins::" #name); | |
| 460 | 510 |
| 461 BUILTIN_LIST_C(DEF_ENTRY_C) | 511 BUILTIN_LIST_C(DEF_ENTRY_C) |
| 462 #undef DEF_ENTRY_C | 512 #undef DEF_ENTRY_C |
| 463 | 513 |
| 464 #define DEF_ENTRY_C(name) \ | 514 #define DEF_ENTRY_C(name) \ |
| 465 Add(Builtins::builtin_address(Builtins::name), \ | 515 { BUILTIN, \ |
| 466 BUILTIN, \ | 516 Builtins::name, \ |
| 467 Builtins::name, \ | 517 "Builtins::" #name }, |
| 468 "Builtins::" #name); | |
| 469 #define DEF_ENTRY_A(name, kind, state) DEF_ENTRY_C(name) | 518 #define DEF_ENTRY_A(name, kind, state) DEF_ENTRY_C(name) |
| 470 | 519 |
| 471 BUILTIN_LIST_C(DEF_ENTRY_C) | 520 BUILTIN_LIST_C(DEF_ENTRY_C) |
| 472 BUILTIN_LIST_A(DEF_ENTRY_A) | 521 BUILTIN_LIST_A(DEF_ENTRY_A) |
| 473 BUILTIN_LIST_DEBUG_A(DEF_ENTRY_A) | 522 BUILTIN_LIST_DEBUG_A(DEF_ENTRY_A) |
| 474 #undef DEF_ENTRY_C | 523 #undef DEF_ENTRY_C |
| 475 #undef DEF_ENTRY_A | 524 #undef DEF_ENTRY_A |
| 476 | 525 |
| 477 // Runtime functions | 526 // Runtime functions |
| 478 #define RUNTIME_ENTRY(name, nargs) \ | 527 #define RUNTIME_ENTRY(name, nargs) \ |
| 479 Add(Runtime::FunctionForId(Runtime::k##name)->entry, \ | 528 { RUNTIME_FUNCTION, \ |
| 480 RUNTIME_FUNCTION, \ | 529 Runtime::k##name, \ |
| 481 Runtime::k##name, \ | 530 "Runtime::" #name }, |
| 482 "Runtime::" #name); | |
| 483 | 531 |
| 484 RUNTIME_FUNCTION_LIST(RUNTIME_ENTRY) | 532 RUNTIME_FUNCTION_LIST(RUNTIME_ENTRY) |
| 485 #undef RUNTIME_ENTRY | 533 #undef RUNTIME_ENTRY |
| 486 | 534 |
| 487 // IC utilities | 535 // IC utilities |
| 488 #define IC_ENTRY(name) \ | 536 #define IC_ENTRY(name) \ |
| 489 Add(IC::AddressFromUtilityId(IC::k##name), \ | 537 { IC_UTILITY, \ |
| 490 IC_UTILITY, \ | 538 IC::k##name, \ |
| 491 IC::k##name, \ | 539 "IC::" #name }, |
| 492 "IC::" #name); | |
| 493 | 540 |
| 494 IC_UTIL_LIST(IC_ENTRY) | 541 IC_UTIL_LIST(IC_ENTRY) |
| 495 #undef IC_ENTRY | 542 #undef IC_ENTRY |
| 496 | 543 |
| 544 }; // end of ref_table[]. |
| 545 |
| 546 for (size_t i = 0; i < ARRAY_SIZE(ref_table); ++i) { |
| 547 AddFromId(ref_table[i].type, ref_table[i].id, ref_table[i].name); |
| 548 } |
| 549 |
| 497 // Debug addresses | 550 // Debug addresses |
| 498 Add(Debug_Address(Debug::k_after_break_target_address).address(), | 551 Add(Debug_Address(Debug::k_after_break_target_address).address(), |
| 499 DEBUG_ADDRESS, | 552 DEBUG_ADDRESS, |
| 500 Debug::k_after_break_target_address << kDebugIdShift, | 553 Debug::k_after_break_target_address << kDebugIdShift, |
| 501 "Debug::after_break_target_address()"); | 554 "Debug::after_break_target_address()"); |
| 502 Add(Debug_Address(Debug::k_debug_break_return_address).address(), | 555 Add(Debug_Address(Debug::k_debug_break_return_address).address(), |
| 503 DEBUG_ADDRESS, | 556 DEBUG_ADDRESS, |
| 504 Debug::k_debug_break_return_address << kDebugIdShift, | 557 Debug::k_debug_break_return_address << kDebugIdShift, |
| 505 "Debug::debug_break_return_address()"); | 558 "Debug::debug_break_return_address()"); |
| 506 const char* debug_register_format = "Debug::register_address(%i)"; | 559 const char* debug_register_format = "Debug::register_address(%i)"; |
| 507 size_t dr_format_length = strlen(debug_register_format); | 560 size_t dr_format_length = strlen(debug_register_format); |
| 508 for (int i = 0; i < kNumJSCallerSaved; ++i) { | 561 for (int i = 0; i < kNumJSCallerSaved; ++i) { |
| 509 Vector<char> name = Vector<char>::New(dr_format_length + 1); | 562 Vector<char> name = Vector<char>::New(dr_format_length + 1); |
| 510 OS::SNPrintF(name, debug_register_format, i); | 563 OS::SNPrintF(name, debug_register_format, i); |
| 511 Add(Debug_Address(Debug::k_register_address, i).address(), | 564 Add(Debug_Address(Debug::k_register_address, i).address(), |
| 512 DEBUG_ADDRESS, | 565 DEBUG_ADDRESS, |
| 513 Debug::k_register_address << kDebugIdShift | i, | 566 Debug::k_register_address << kDebugIdShift | i, |
| 514 name.start()); | 567 name.start()); |
| 515 } | 568 } |
| 516 | 569 |
| 517 // Stat counters | 570 // Stat counters |
| 571 struct StatsRefTableEntry { |
| 572 StatsCounter* counter; |
| 573 uint16_t id; |
| 574 const char* name; |
| 575 }; |
| 576 |
| 577 static const StatsRefTableEntry stats_ref_table[] = { |
| 578 |
| 518 #define COUNTER_ENTRY(name, caption) \ | 579 #define COUNTER_ENTRY(name, caption) \ |
| 519 Add(reinterpret_cast<Address>(GetInternalPointer(&Counters::name)), \ | 580 { &Counters::name, \ |
| 520 STATS_COUNTER, \ | 581 Counters::k_##name, \ |
| 521 Counters::k_##name, \ | 582 "Counters::" #name }, |
| 522 "Counters::" #name); | |
| 523 | 583 |
| 524 STATS_COUNTER_LIST_1(COUNTER_ENTRY) | 584 STATS_COUNTER_LIST_1(COUNTER_ENTRY) |
| 525 STATS_COUNTER_LIST_2(COUNTER_ENTRY) | 585 STATS_COUNTER_LIST_2(COUNTER_ENTRY) |
| 526 #undef COUNTER_ENTRY | 586 #undef COUNTER_ENTRY |
| 527 | 587 |
| 588 }; // end of stats_ref_table[]. |
| 589 |
| 590 for (size_t i = 0; i < ARRAY_SIZE(stats_ref_table); ++i) { |
| 591 Add(reinterpret_cast<Address>( |
| 592 GetInternalPointer(stats_ref_table[i].counter)), |
| 593 STATS_COUNTER, |
| 594 stats_ref_table[i].id, |
| 595 stats_ref_table[i].name); |
| 596 } |
| 597 |
| 528 // Top addresses | 598 // Top addresses |
| 529 const char* top_address_format = "Top::get_address_from_id(%i)"; | 599 const char* top_address_format = "Top::get_address_from_id(%i)"; |
| 530 size_t top_format_length = strlen(top_address_format); | 600 size_t top_format_length = strlen(top_address_format); |
| 531 for (uint16_t i = 0; i < Top::k_top_address_count; ++i) { | 601 for (uint16_t i = 0; i < Top::k_top_address_count; ++i) { |
| 532 Vector<char> name = Vector<char>::New(top_format_length + 1); | 602 Vector<char> name = Vector<char>::New(top_format_length + 1); |
| 533 const char* chars = name.start(); | 603 const char* chars = name.start(); |
| 534 OS::SNPrintF(name, top_address_format, i); | 604 OS::SNPrintF(name, top_address_format, i); |
| 535 Add(Top::get_address_from_id((Top::AddressId)i), TOP_ADDRESS, i, chars); | 605 Add(Top::get_address_from_id((Top::AddressId)i), TOP_ADDRESS, i, chars); |
| 536 } | 606 } |
| 537 | 607 |
| (...skipping 980 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1518 ASSERT(index < large_objects_.length()); | 1588 ASSERT(index < large_objects_.length()); |
| 1519 } | 1589 } |
| 1520 return large_objects_[index]; // s.page_offset() is ignored. | 1590 return large_objects_[index]; // s.page_offset() is ignored. |
| 1521 } | 1591 } |
| 1522 UNREACHABLE(); | 1592 UNREACHABLE(); |
| 1523 return NULL; | 1593 return NULL; |
| 1524 } | 1594 } |
| 1525 | 1595 |
| 1526 | 1596 |
| 1527 } } // namespace v8::internal | 1597 } } // namespace v8::internal |
| OLD | NEW |