| 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 26 matching lines...) Expand all Loading... |
| 37 #include "runtime.h" | 37 #include "runtime.h" |
| 38 #include "serialize.h" | 38 #include "serialize.h" |
| 39 #include "stub-cache.h" | 39 #include "stub-cache.h" |
| 40 #include "v8threads.h" | 40 #include "v8threads.h" |
| 41 #include "top.h" | 41 #include "top.h" |
| 42 #include "bootstrapper.h" | 42 #include "bootstrapper.h" |
| 43 | 43 |
| 44 namespace v8 { | 44 namespace v8 { |
| 45 namespace internal { | 45 namespace internal { |
| 46 | 46 |
| 47 class ExternalReferenceTable; |
| 48 |
| 49 class SerializerPrivateData { |
| 50 public: |
| 51 ExternalReferenceTable* external_reference_table_; |
| 52 HashMap* serialization_map_; |
| 53 SerializerPrivateData() |
| 54 :serialization_map_(NULL), |
| 55 external_reference_table_(NULL) { |
| 56 } |
| 57 }; |
| 58 |
| 59 SerializerData::SerializerData() |
| 60 :private_data_(*new SerializerPrivateData()), |
| 61 serialization_enabled_(false), |
| 62 too_late_to_enable_now_(false) { |
| 63 } |
| 64 |
| 65 SerializerData::~SerializerData() { |
| 66 delete &private_data_; |
| 67 } |
| 68 |
| 47 // Mapping objects to their location after deserialization. | 69 // Mapping objects to their location after deserialization. |
| 48 // This is used during building, but not at runtime by V8. | 70 // This is used during building, but not at runtime by V8. |
| 49 class SerializationAddressMapper { | 71 class SerializationAddressMapper { |
| 50 public: | 72 public: |
| 51 static bool IsMapped(HeapObject* obj) { | 73 static bool IsMapped(HeapObject* obj) { |
| 52 EnsureMapExists(); | 74 EnsureMapExists(); |
| 53 return serialization_map_->Lookup(Key(obj), Hash(obj), false) != NULL; | 75 return v8_context()->serializer_data_.private_data_. |
| 76 serialization_map_->Lookup(Key(obj), Hash(obj), false) != NULL; |
| 54 } | 77 } |
| 55 | 78 |
| 56 static int MappedTo(HeapObject* obj) { | 79 static int MappedTo(HeapObject* obj) { |
| 57 ASSERT(IsMapped(obj)); | 80 ASSERT(IsMapped(obj)); |
| 58 return reinterpret_cast<intptr_t>(serialization_map_->Lookup(Key(obj), | 81 return reinterpret_cast<intptr_t>(v8_context()->serializer_data_. |
| 59 Hash(obj), | 82 private_data_.serialization_map_->Lookup( |
| 60 false)->value); | 83 Key(obj), |
| 84 Hash(obj), |
| 85 false)->value); |
| 61 } | 86 } |
| 62 | 87 |
| 63 static void Map(HeapObject* obj, int to) { | 88 static void Map(HeapObject* obj, int to) { |
| 64 EnsureMapExists(); | 89 EnsureMapExists(); |
| 65 ASSERT(!IsMapped(obj)); | 90 ASSERT(!IsMapped(obj)); |
| 66 HashMap::Entry* entry = | 91 HashMap::Entry* entry = v8_context()->serializer_data_.private_data_. |
| 67 serialization_map_->Lookup(Key(obj), Hash(obj), true); | 92 serialization_map_->Lookup(Key(obj), Hash(obj), true); |
| 68 entry->value = Value(to); | 93 entry->value = Value(to); |
| 69 } | 94 } |
| 70 | 95 |
| 71 static void Zap() { | 96 static void Zap() { |
| 72 if (serialization_map_ != NULL) { | 97 HashMap*& serialization_map = v8_context()->serializer_data_. |
| 73 delete serialization_map_; | 98 private_data_.serialization_map_; |
| 99 if (serialization_map != NULL) { |
| 100 delete serialization_map; |
| 74 } | 101 } |
| 75 serialization_map_ = NULL; | 102 serialization_map = NULL; |
| 76 } | 103 } |
| 77 | 104 |
| 78 private: | 105 private: |
| 79 static bool SerializationMatchFun(void* key1, void* key2) { | 106 static bool SerializationMatchFun(void* key1, void* key2) { |
| 80 return key1 == key2; | 107 return key1 == key2; |
| 81 } | 108 } |
| 82 | 109 |
| 83 static uint32_t Hash(HeapObject* obj) { | 110 static uint32_t Hash(HeapObject* obj) { |
| 84 return reinterpret_cast<intptr_t>(obj->address()); | 111 return reinterpret_cast<intptr_t>(obj->address()); |
| 85 } | 112 } |
| 86 | 113 |
| 87 static void* Key(HeapObject* obj) { | 114 static void* Key(HeapObject* obj) { |
| 88 return reinterpret_cast<void*>(obj->address()); | 115 return reinterpret_cast<void*>(obj->address()); |
| 89 } | 116 } |
| 90 | 117 |
| 91 static void* Value(int v) { | 118 static void* Value(int v) { |
| 92 return reinterpret_cast<void*>(v); | 119 return reinterpret_cast<void*>(v); |
| 93 } | 120 } |
| 94 | 121 |
| 95 static void EnsureMapExists() { | 122 static void EnsureMapExists() { |
| 96 if (serialization_map_ == NULL) { | 123 HashMap*& serialization_map = v8_context()->serializer_data_. |
| 97 serialization_map_ = new HashMap(&SerializationMatchFun); | 124 private_data_.serialization_map_; |
| 125 if (serialization_map == NULL) { |
| 126 serialization_map = new HashMap(&SerializationMatchFun); |
| 98 } | 127 } |
| 99 } | 128 } |
| 100 | |
| 101 static HashMap* serialization_map_; | |
| 102 }; | 129 }; |
| 103 | 130 |
| 104 | 131 |
| 105 HashMap* SerializationAddressMapper::serialization_map_ = NULL; | |
| 106 | 132 |
| 107 | 133 |
| 108 | 134 |
| 109 | 135 |
| 110 // ----------------------------------------------------------------------------- | 136 // ----------------------------------------------------------------------------- |
| 111 // Coding of external references. | 137 // Coding of external references. |
| 112 | 138 |
| 113 // The encoding of an external reference. The type is in the high word. | 139 // The encoding of an external reference. The type is in the high word. |
| 114 // The id is in the low word. | 140 // The id is in the low word. |
| 115 static uint32_t EncodeExternal(TypeCode type, uint16_t id) { | 141 static uint32_t EncodeExternal(TypeCode type, uint16_t id) { |
| 116 return static_cast<uint32_t>(type) << 16 | id; | 142 return static_cast<uint32_t>(type) << 16 | id; |
| 117 } | 143 } |
| 118 | 144 |
| 119 | 145 |
| 120 static int* GetInternalPointer(StatsCounter* counter) { | 146 static int* GetInternalPointer(StatsCounter* counter) { |
| 121 // All counters refer to dummy_counter, if deserializing happens without | 147 // All counters refer to dummy_counter, if deserializing happens without |
| 122 // setting up counters. | 148 // setting up counters. |
| 123 static int dummy_counter = 0; | 149 static int dummy_counter = 0; |
| 124 return counter->Enabled() ? counter->GetInternalPointer() : &dummy_counter; | 150 return counter->Enabled() ? counter->GetInternalPointer() : &dummy_counter; |
| 125 } | 151 } |
| 126 | 152 |
| 127 | 153 |
| 128 // ExternalReferenceTable is a helper class that defines the relationship | 154 // ExternalReferenceTable is a helper class that defines the relationship |
| 129 // between external references and their encodings. It is used to build | 155 // between external references and their encodings. It is used to build |
| 130 // hashmaps in ExternalReferenceEncoder and ExternalReferenceDecoder. | 156 // hashmaps in ExternalReferenceEncoder and ExternalReferenceDecoder. |
| 131 class ExternalReferenceTable { | 157 class ExternalReferenceTable { |
| 132 public: | 158 public: |
| 133 static ExternalReferenceTable* instance() { | 159 static ExternalReferenceTable* instance() { |
| 134 if (!instance_) instance_ = new ExternalReferenceTable(); | 160 ExternalReferenceTable*& instance = v8_context()->serializer_data_. |
| 135 return instance_; | 161 private_data_.external_reference_table_; |
| 162 if (!instance) instance = new ExternalReferenceTable(); |
| 163 return instance; |
| 136 } | 164 } |
| 137 | 165 |
| 138 int size() const { return refs_.length(); } | 166 int size() const { return refs_.length(); } |
| 139 | 167 |
| 140 Address address(int i) { return refs_[i].address; } | 168 Address address(int i) { return refs_[i].address; } |
| 141 | 169 |
| 142 uint32_t code(int i) { return refs_[i].code; } | 170 uint32_t code(int i) { return refs_[i].code; } |
| 143 | 171 |
| 144 const char* name(int i) { return refs_[i].name; } | 172 const char* name(int i) { return refs_[i].name; } |
| 145 | 173 |
| 146 int max_id(int code) { return max_id_[code]; } | 174 int max_id(int code) { return max_id_[code]; } |
| 147 | 175 |
| 148 private: | 176 private: |
| 149 static ExternalReferenceTable* instance_; | |
| 150 | 177 |
| 151 ExternalReferenceTable() : refs_(64) { PopulateTable(); } | 178 ExternalReferenceTable() : refs_(64) { PopulateTable(); } |
| 152 ~ExternalReferenceTable() { } | 179 ~ExternalReferenceTable() { } |
| 153 | 180 |
| 154 struct ExternalReferenceEntry { | 181 struct ExternalReferenceEntry { |
| 155 Address address; | 182 Address address; |
| 156 uint32_t code; | 183 uint32_t code; |
| 157 const char* name; | 184 const char* name; |
| 158 }; | 185 }; |
| 159 | 186 |
| 160 void PopulateTable(); | 187 void PopulateTable(); |
| 161 | 188 |
| 162 // For a few types of references, we can get their address from their id. | 189 // For a few types of references, we can get their address from their id. |
| 163 void AddFromId(TypeCode type, uint16_t id, const char* name); | 190 void AddFromId(TypeCode type, uint16_t id, const char* name); |
| 164 | 191 |
| 165 // For other types of references, the caller will figure out the address. | 192 // For other types of references, the caller will figure out the address. |
| 166 void Add(Address address, TypeCode type, uint16_t id, const char* name); | 193 void Add(Address address, TypeCode type, uint16_t id, const char* name); |
| 167 | 194 |
| 168 List<ExternalReferenceEntry> refs_; | 195 List<ExternalReferenceEntry> refs_; |
| 169 int max_id_[kTypeCodeCount]; | 196 int max_id_[kTypeCodeCount]; |
| 170 }; | 197 }; |
| 171 | 198 |
| 172 | 199 |
| 173 ExternalReferenceTable* ExternalReferenceTable::instance_ = NULL; | |
| 174 | 200 |
| 175 | 201 |
| 176 void ExternalReferenceTable::AddFromId(TypeCode type, | 202 void ExternalReferenceTable::AddFromId(TypeCode type, |
| 177 uint16_t id, | 203 uint16_t id, |
| 178 const char* name) { | 204 const char* name) { |
| 179 Address address; | 205 Address address; |
| 180 switch (type) { | 206 switch (type) { |
| 181 case C_BUILTIN: { | 207 case C_BUILTIN: { |
| 182 ExternalReference ref(static_cast<Builtins::CFunctionId>(id)); | 208 ExternalReference ref(static_cast<Builtins::CFunctionId>(id)); |
| 183 address = ref.address(); | 209 address = ref.address(); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 | 335 |
| 310 // Stat counters | 336 // Stat counters |
| 311 struct StatsRefTableEntry { | 337 struct StatsRefTableEntry { |
| 312 StatsCounter* counter; | 338 StatsCounter* counter; |
| 313 uint16_t id; | 339 uint16_t id; |
| 314 const char* name; | 340 const char* name; |
| 315 }; | 341 }; |
| 316 | 342 |
| 317 static const StatsRefTableEntry stats_ref_table[] = { | 343 static const StatsRefTableEntry stats_ref_table[] = { |
| 318 #define COUNTER_ENTRY(name, caption) \ | 344 #define COUNTER_ENTRY(name, caption) \ |
| 319 { &Counters::name, \ | 345 { &COUNTER(name), \ |
| 320 Counters::k_##name, \ | 346 Counters::k_##name, \ |
| 321 "Counters::" #name }, | 347 "Counters::" #name }, |
| 322 | 348 |
| 323 STATS_COUNTER_LIST_1(COUNTER_ENTRY) | 349 STATS_COUNTER_LIST_1(COUNTER_ENTRY) |
| 324 STATS_COUNTER_LIST_2(COUNTER_ENTRY) | 350 STATS_COUNTER_LIST_2(COUNTER_ENTRY) |
| 325 #undef COUNTER_ENTRY | 351 #undef COUNTER_ENTRY |
| 326 }; // end of stats_ref_table[]. | 352 }; // end of stats_ref_table[]. |
| 327 | 353 |
| 328 for (size_t i = 0; i < ARRAY_SIZE(stats_ref_table); ++i) { | 354 for (size_t i = 0; i < ARRAY_SIZE(stats_ref_table); ++i) { |
| 329 Add(reinterpret_cast<Address>( | 355 Add(reinterpret_cast<Address>( |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 541 | 567 |
| 542 | 568 |
| 543 ExternalReferenceDecoder::~ExternalReferenceDecoder() { | 569 ExternalReferenceDecoder::~ExternalReferenceDecoder() { |
| 544 for (int type = kFirstTypeCode; type < kTypeCodeCount; ++type) { | 570 for (int type = kFirstTypeCode; type < kTypeCodeCount; ++type) { |
| 545 DeleteArray(encodings_[type]); | 571 DeleteArray(encodings_[type]); |
| 546 } | 572 } |
| 547 DeleteArray(encodings_); | 573 DeleteArray(encodings_); |
| 548 } | 574 } |
| 549 | 575 |
| 550 | 576 |
| 551 bool Serializer::serialization_enabled_ = false; | |
| 552 bool Serializer::too_late_to_enable_now_ = false; | |
| 553 | |
| 554 | 577 |
| 555 Deserializer::Deserializer(SnapshotByteSource* source) | 578 Deserializer::Deserializer(SnapshotByteSource* source) |
| 556 : source_(source), | 579 : source_(source), |
| 557 external_reference_decoder_(NULL) { | 580 external_reference_decoder_(NULL) { |
| 558 } | 581 } |
| 559 | 582 |
| 560 | 583 |
| 561 // This routine both allocates a new object, and also keeps | 584 // This routine both allocates a new object, and also keeps |
| 562 // track of where objects have been allocated so that we can | 585 // track of where objects have been allocated so that we can |
| 563 // fix back references when deserializing. | 586 // fix back references when deserializing. |
| (...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1213 fullness_[space] = RoundUp(fullness_[space], Page::kPageSize); | 1236 fullness_[space] = RoundUp(fullness_[space], Page::kPageSize); |
| 1214 } | 1237 } |
| 1215 } | 1238 } |
| 1216 int allocation_address = fullness_[space]; | 1239 int allocation_address = fullness_[space]; |
| 1217 fullness_[space] = allocation_address + size; | 1240 fullness_[space] = allocation_address + size; |
| 1218 return allocation_address; | 1241 return allocation_address; |
| 1219 } | 1242 } |
| 1220 | 1243 |
| 1221 | 1244 |
| 1222 } } // namespace v8::internal | 1245 } } // namespace v8::internal |
| OLD | NEW |