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 |