Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(357)

Side by Side Diff: src/serialize.cc

Issue 982773003: Serializer: simplify external reference encoding. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebase Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/serialize.h ('k') | test/cctest/test-serialize.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/api.h" 8 #include "src/api.h"
9 #include "src/base/platform/platform.h" 9 #include "src/base/platform/platform.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 14 matching lines...) Expand all
25 #include "src/v8threads.h" 25 #include "src/v8threads.h"
26 #include "src/version.h" 26 #include "src/version.h"
27 27
28 namespace v8 { 28 namespace v8 {
29 namespace internal { 29 namespace internal {
30 30
31 31
32 // ----------------------------------------------------------------------------- 32 // -----------------------------------------------------------------------------
33 // Coding of external references. 33 // Coding of external references.
34 34
35 // The encoding of an external reference. The type is in the high word.
36 // The id is in the low word.
37 static uint32_t EncodeExternal(TypeCode type, uint16_t id) {
38 return static_cast<uint32_t>(type) << 16 | id;
39 }
40
41
42 static int* GetInternalPointer(StatsCounter* counter) {
43 // All counters refer to dummy_counter, if deserializing happens without
44 // setting up counters.
45 static int dummy_counter = 0;
46 return counter->Enabled() ? counter->GetInternalPointer() : &dummy_counter;
47 }
48
49 35
50 ExternalReferenceTable* ExternalReferenceTable::instance(Isolate* isolate) { 36 ExternalReferenceTable* ExternalReferenceTable::instance(Isolate* isolate) {
51 ExternalReferenceTable* external_reference_table = 37 ExternalReferenceTable* external_reference_table =
52 isolate->external_reference_table(); 38 isolate->external_reference_table();
53 if (external_reference_table == NULL) { 39 if (external_reference_table == NULL) {
54 external_reference_table = new ExternalReferenceTable(isolate); 40 external_reference_table = new ExternalReferenceTable(isolate);
55 isolate->set_external_reference_table(external_reference_table); 41 isolate->set_external_reference_table(external_reference_table);
56 } 42 }
57 return external_reference_table; 43 return external_reference_table;
58 } 44 }
59 45
60 46
61 void ExternalReferenceTable::AddFromId(TypeCode type, 47 ExternalReferenceTable::ExternalReferenceTable(Isolate* isolate) {
62 uint16_t id,
63 const char* name,
64 Isolate* isolate) {
65 Address address;
66 switch (type) {
67 case C_BUILTIN: {
68 ExternalReference ref(static_cast<Builtins::CFunctionId>(id), isolate);
69 address = ref.address();
70 break;
71 }
72 case BUILTIN: {
73 ExternalReference ref(static_cast<Builtins::Name>(id), isolate);
74 address = ref.address();
75 break;
76 }
77 case RUNTIME_FUNCTION: {
78 ExternalReference ref(static_cast<Runtime::FunctionId>(id), isolate);
79 address = ref.address();
80 break;
81 }
82 case IC_UTILITY: {
83 ExternalReference ref(IC_Utility(static_cast<IC::UtilityId>(id)),
84 isolate);
85 address = ref.address();
86 break;
87 }
88 default:
89 UNREACHABLE();
90 return;
91 }
92 Add(address, type, id, name);
93 }
94
95
96 void ExternalReferenceTable::Add(Address address,
97 TypeCode type,
98 uint16_t id,
99 const char* name) {
100 DCHECK_NOT_NULL(address);
101 ExternalReferenceEntry entry;
102 entry.address = address;
103 entry.code = EncodeExternal(type, id);
104 entry.name = name;
105 DCHECK_NE(0u, entry.code);
106 // Assert that the code is added in ascending order to rule out duplicates.
107 DCHECK((size() == 0) || (code(size() - 1) < entry.code));
108 refs_.Add(entry);
109 if (id > max_id_[type]) max_id_[type] = id;
110 }
111
112
113 void ExternalReferenceTable::PopulateTable(Isolate* isolate) {
114 for (int type_code = 0; type_code < kTypeCodeCount; type_code++) {
115 max_id_[type_code] = 0;
116 }
117
118 // Miscellaneous 48 // Miscellaneous
119 Add(ExternalReference::roots_array_start(isolate).address(), 49 Add(ExternalReference::roots_array_start(isolate).address(),
120 "Heap::roots_array_start()"); 50 "Heap::roots_array_start()");
121 Add(ExternalReference::address_of_stack_limit(isolate).address(), 51 Add(ExternalReference::address_of_stack_limit(isolate).address(),
122 "StackGuard::address_of_jslimit()"); 52 "StackGuard::address_of_jslimit()");
123 Add(ExternalReference::address_of_real_stack_limit(isolate).address(), 53 Add(ExternalReference::address_of_real_stack_limit(isolate).address(),
124 "StackGuard::address_of_real_jslimit()"); 54 "StackGuard::address_of_real_jslimit()");
125 Add(ExternalReference::new_space_start(isolate).address(), 55 Add(ExternalReference::new_space_start(isolate).address(),
126 "Heap::NewSpaceStart()"); 56 "Heap::NewSpaceStart()");
127 Add(ExternalReference::new_space_mask(isolate).address(), 57 Add(ExternalReference::new_space_mask(isolate).address(),
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 "date_cache_stamp"); 102 "date_cache_stamp");
173 Add(ExternalReference::address_of_pending_message_obj(isolate).address(), 103 Add(ExternalReference::address_of_pending_message_obj(isolate).address(),
174 "address_of_pending_message_obj"); 104 "address_of_pending_message_obj");
175 Add(ExternalReference::address_of_has_pending_message(isolate).address(), 105 Add(ExternalReference::address_of_has_pending_message(isolate).address(),
176 "address_of_has_pending_message"); 106 "address_of_has_pending_message");
177 Add(ExternalReference::address_of_pending_message_script(isolate).address(), 107 Add(ExternalReference::address_of_pending_message_script(isolate).address(),
178 "pending_message_script"); 108 "pending_message_script");
179 Add(ExternalReference::get_make_code_young_function(isolate).address(), 109 Add(ExternalReference::get_make_code_young_function(isolate).address(),
180 "Code::MakeCodeYoung"); 110 "Code::MakeCodeYoung");
181 Add(ExternalReference::cpu_features().address(), "cpu_features"); 111 Add(ExternalReference::cpu_features().address(), "cpu_features");
182 Add(ExternalReference(Runtime::kAllocateInNewSpace, isolate).address(),
183 "Runtime::AllocateInNewSpace");
184 Add(ExternalReference(Runtime::kAllocateInTargetSpace, isolate).address(),
185 "Runtime::AllocateInTargetSpace");
186 Add(ExternalReference::old_pointer_space_allocation_top_address(isolate) 112 Add(ExternalReference::old_pointer_space_allocation_top_address(isolate)
187 .address(), 113 .address(),
188 "Heap::OldPointerSpaceAllocationTopAddress"); 114 "Heap::OldPointerSpaceAllocationTopAddress");
189 Add(ExternalReference::old_pointer_space_allocation_limit_address(isolate) 115 Add(ExternalReference::old_pointer_space_allocation_limit_address(isolate)
190 .address(), 116 .address(),
191 "Heap::OldPointerSpaceAllocationLimitAddress"); 117 "Heap::OldPointerSpaceAllocationLimitAddress");
192 Add(ExternalReference::old_data_space_allocation_top_address(isolate) 118 Add(ExternalReference::old_data_space_allocation_top_address(isolate)
193 .address(), 119 .address(),
194 "Heap::OldDataSpaceAllocationTopAddress"); 120 "Heap::OldDataSpaceAllocationTopAddress");
195 Add(ExternalReference::old_data_space_allocation_limit_address(isolate) 121 Add(ExternalReference::old_data_space_allocation_limit_address(isolate)
(...skipping 15 matching lines...) Expand all
211 Add(ExternalReference::flush_icache_function(isolate).address(), 137 Add(ExternalReference::flush_icache_function(isolate).address(),
212 "CpuFeatures::FlushICache"); 138 "CpuFeatures::FlushICache");
213 Add(ExternalReference::log_enter_external_function(isolate).address(), 139 Add(ExternalReference::log_enter_external_function(isolate).address(),
214 "Logger::EnterExternal"); 140 "Logger::EnterExternal");
215 Add(ExternalReference::log_leave_external_function(isolate).address(), 141 Add(ExternalReference::log_leave_external_function(isolate).address(),
216 "Logger::LeaveExternal"); 142 "Logger::LeaveExternal");
217 Add(ExternalReference::address_of_minus_one_half().address(), 143 Add(ExternalReference::address_of_minus_one_half().address(),
218 "double_constants.minus_one_half"); 144 "double_constants.minus_one_half");
219 Add(ExternalReference::stress_deopt_count(isolate).address(), 145 Add(ExternalReference::stress_deopt_count(isolate).address(),
220 "Isolate::stress_deopt_count_address()"); 146 "Isolate::stress_deopt_count_address()");
221 Add(ExternalReference::incremental_marking_record_write_function(isolate)
222 .address(),
223 "IncrementalMarking::RecordWriteFromCode");
224 147
225 // Debug addresses 148 // Debug addresses
226 Add(ExternalReference::debug_after_break_target_address(isolate).address(), 149 Add(ExternalReference::debug_after_break_target_address(isolate).address(),
227 "Debug::after_break_target_address()"); 150 "Debug::after_break_target_address()");
228 Add(ExternalReference::debug_restarter_frame_function_pointer_address(isolate) 151 Add(ExternalReference::debug_restarter_frame_function_pointer_address(isolate)
229 .address(), 152 .address(),
230 "Debug::restarter_frame_function_pointer_address()"); 153 "Debug::restarter_frame_function_pointer_address()");
231 Add(ExternalReference::debug_is_active_address(isolate).address(), 154 Add(ExternalReference::debug_is_active_address(isolate).address(),
232 "Debug::is_active_address()"); 155 "Debug::is_active_address()");
233 156
(...skipping 19 matching lines...) Expand all
253 176
254 // The following populates all of the different type of external references 177 // The following populates all of the different type of external references
255 // into the ExternalReferenceTable. 178 // into the ExternalReferenceTable.
256 // 179 //
257 // NOTE: This function was originally 100k of code. It has since been 180 // NOTE: This function was originally 100k of code. It has since been
258 // rewritten to be mostly table driven, as the callback macro style tends to 181 // rewritten to be mostly table driven, as the callback macro style tends to
259 // very easily cause code bloat. Please be careful in the future when adding 182 // very easily cause code bloat. Please be careful in the future when adding
260 // new references. 183 // new references.
261 184
262 struct RefTableEntry { 185 struct RefTableEntry {
263 TypeCode type;
264 uint16_t id; 186 uint16_t id;
265 const char* name; 187 const char* name;
266 }; 188 };
267 189
268 static const RefTableEntry ref_table[] = { 190 static const RefTableEntry c_builtins[] = {
269 // Builtins 191 #define DEF_ENTRY_C(name, ignored) \
270 #define DEF_ENTRY_C(name, ignored) \ 192 { Builtins::c_##name, "Builtins::" #name } \
271 { C_BUILTIN, \ 193 ,
272 Builtins::c_##name, \ 194 BUILTIN_LIST_C(DEF_ENTRY_C)
273 "Builtins::" #name }, 195 #undef DEF_ENTRY_C
196 };
274 197
275 BUILTIN_LIST_C(DEF_ENTRY_C) 198 for (unsigned i = 0; i < arraysize(c_builtins); ++i) {
276 #undef DEF_ENTRY_C 199 ExternalReference ref(static_cast<Builtins::CFunctionId>(c_builtins[i].id),
200 isolate);
201 Add(ref.address(), c_builtins[i].name);
202 }
277 203
278 #define DEF_ENTRY_C(name, ignored) \ 204 static const RefTableEntry builtins[] = {
279 { BUILTIN, \ 205 #define DEF_ENTRY_C(name, ignored) \
280 Builtins::k##name, \ 206 { Builtins::k##name, "Builtins::" #name } \
281 "Builtins::" #name }, 207 ,
282 #define DEF_ENTRY_A(name, kind, state, extra) DEF_ENTRY_C(name, ignored) 208 #define DEF_ENTRY_A(name, i1, i2, i3) \
283 209 { Builtins::k##name, "Builtins::" #name } \
284 BUILTIN_LIST_C(DEF_ENTRY_C) 210 ,
285 BUILTIN_LIST_A(DEF_ENTRY_A) 211 BUILTIN_LIST_C(DEF_ENTRY_C) BUILTIN_LIST_A(DEF_ENTRY_A)
286 BUILTIN_LIST_DEBUG_A(DEF_ENTRY_A) 212 BUILTIN_LIST_DEBUG_A(DEF_ENTRY_A)
287 #undef DEF_ENTRY_C 213 #undef DEF_ENTRY_C
288 #undef DEF_ENTRY_A 214 #undef DEF_ENTRY_A
215 };
289 216
290 // Runtime functions 217 for (unsigned i = 0; i < arraysize(builtins); ++i) {
291 #define RUNTIME_ENTRY(name, nargs, ressize) \ 218 ExternalReference ref(static_cast<Builtins::Name>(builtins[i].id), isolate);
292 { RUNTIME_FUNCTION, \ 219 Add(ref.address(), builtins[i].name);
293 Runtime::k##name, \ 220 }
294 "Runtime::" #name },
295 221
296 RUNTIME_FUNCTION_LIST(RUNTIME_ENTRY) 222 static const RefTableEntry runtime_functions[] = {
297 INLINE_OPTIMIZED_FUNCTION_LIST(RUNTIME_ENTRY) 223 #define RUNTIME_ENTRY(name, i1, i2) \
224 { Runtime::k##name, "Runtime::" #name } \
225 ,
226 RUNTIME_FUNCTION_LIST(RUNTIME_ENTRY)
227 INLINE_OPTIMIZED_FUNCTION_LIST(RUNTIME_ENTRY)
298 #undef RUNTIME_ENTRY 228 #undef RUNTIME_ENTRY
229 };
299 230
300 #define INLINE_OPTIMIZED_ENTRY(name, nargs, ressize) \ 231 for (unsigned i = 0; i < arraysize(runtime_functions); ++i) {
301 { RUNTIME_FUNCTION, \ 232 ExternalReference ref(
302 Runtime::kInlineOptimized##name, \ 233 static_cast<Runtime::FunctionId>(runtime_functions[i].id), isolate);
303 "Runtime::" #name }, 234 Add(ref.address(), runtime_functions[i].name);
235 }
304 236
305 INLINE_OPTIMIZED_FUNCTION_LIST(INLINE_OPTIMIZED_ENTRY) 237 static const RefTableEntry inline_caches[] = {
306 #undef INLINE_OPTIMIZED_ENTRY 238 #define IC_ENTRY(name) \
239 { IC::k##name, "IC::" #name } \
240 ,
241 IC_UTIL_LIST(IC_ENTRY)
242 #undef IC_ENTRY
243 };
307 244
308 // IC utilities 245 for (unsigned i = 0; i < arraysize(inline_caches); ++i) {
309 #define IC_ENTRY(name) \ 246 ExternalReference ref(
310 { IC_UTILITY, \ 247 IC_Utility(static_cast<IC::UtilityId>(inline_caches[i].id)), isolate);
311 IC::k##name, \ 248 Add(ref.address(), runtime_functions[i].name);
312 "IC::" #name },
313
314 IC_UTIL_LIST(IC_ENTRY)
315 #undef IC_ENTRY
316 }; // end of ref_table[].
317
318 for (size_t i = 0; i < arraysize(ref_table); ++i) {
319 AddFromId(ref_table[i].type,
320 ref_table[i].id,
321 ref_table[i].name,
322 isolate);
323 } 249 }
324 250
325 // Stat counters 251 // Stat counters
326 struct StatsRefTableEntry { 252 struct StatsRefTableEntry {
327 StatsCounter* (Counters::*counter)(); 253 StatsCounter* (Counters::*counter)();
328 uint16_t id;
329 const char* name; 254 const char* name;
330 }; 255 };
331 256
332 const StatsRefTableEntry stats_ref_table[] = { 257 static const StatsRefTableEntry stats_ref_table[] = {
333 #define COUNTER_ENTRY(name, caption) \ 258 #define COUNTER_ENTRY(name, caption) \
334 { &Counters::name, \ 259 { &Counters::name, "Counters::" #name } \
335 Counters::k_##name, \ 260 ,
336 "Counters::" #name }, 261 STATS_COUNTER_LIST_1(COUNTER_ENTRY) STATS_COUNTER_LIST_2(COUNTER_ENTRY)
337
338 STATS_COUNTER_LIST_1(COUNTER_ENTRY)
339 STATS_COUNTER_LIST_2(COUNTER_ENTRY)
340 #undef COUNTER_ENTRY 262 #undef COUNTER_ENTRY
341 }; // end of stats_ref_table[]. 263 };
342 264
343 Counters* counters = isolate->counters(); 265 Counters* counters = isolate->counters();
344 for (size_t i = 0; i < arraysize(stats_ref_table); ++i) { 266 for (unsigned i = 0; i < arraysize(stats_ref_table); ++i) {
345 Add(reinterpret_cast<Address>(GetInternalPointer( 267 // To make sure the indices are not dependent on whether counters are
346 (counters->*(stats_ref_table[i].counter))())), 268 // enabled, use a dummy address as filler.
347 STATS_COUNTER, 269 Address address = NotAvailable();
348 stats_ref_table[i].id, 270 StatsCounter* counter = (counters->*(stats_ref_table[i].counter))();
349 stats_ref_table[i].name); 271 if (counter->Enabled()) {
272 address = reinterpret_cast<Address>(counter->GetInternalPointer());
273 }
274 Add(address, stats_ref_table[i].name);
350 } 275 }
351 276
352 // Top addresses 277 // Top addresses
353 278 static const char* address_names[] = {
354 const char* AddressNames[] = { 279 #define BUILD_NAME_LITERAL(Name, name) "Isolate::" #name "_address",
355 #define BUILD_NAME_LITERAL(CamelName, hacker_name) \ 280 FOR_EACH_ISOLATE_ADDRESS_NAME(BUILD_NAME_LITERAL) NULL
356 "Isolate::" #hacker_name "_address",
357 FOR_EACH_ISOLATE_ADDRESS_NAME(BUILD_NAME_LITERAL)
358 NULL
359 #undef BUILD_NAME_LITERAL 281 #undef BUILD_NAME_LITERAL
360 }; 282 };
361 283
362 for (uint16_t i = 0; i < Isolate::kIsolateAddressCount; ++i) { 284 for (int i = 0; i < Isolate::kIsolateAddressCount; ++i) {
363 Add(isolate->get_address_from_id((Isolate::AddressId)i), 285 Add(isolate->get_address_from_id(static_cast<Isolate::AddressId>(i)),
364 TOP_ADDRESS, i, AddressNames[i]); 286 address_names[i]);
365 } 287 }
366 288
367 // Accessors 289 // Accessors
368 #define ACCESSOR_INFO_DECLARATION(name) \ 290 struct AccessorRefTable {
369 Add(FUNCTION_ADDR(&Accessors::name##Getter), ACCESSOR_CODE, \ 291 Address address;
370 Accessors::k##name##Getter, "Accessors::" #name "Getter"); \ 292 const char* name;
371 Add(FUNCTION_ADDR(&Accessors::name##Setter), ACCESSOR_CODE, \ 293 };
372 Accessors::k##name##Setter, "Accessors::" #name "Setter"); 294
373 ACCESSOR_INFO_LIST(ACCESSOR_INFO_DECLARATION) 295 static const AccessorRefTable accessors[] = {
296 #define ACCESSOR_INFO_DECLARATION(name) \
297 { FUNCTION_ADDR(&Accessors::name##Getter), "Accessors::" #name "Getter" } \
298 , {FUNCTION_ADDR(&Accessors::name##Setter), "Accessors::" #name "Setter"},
299 ACCESSOR_INFO_LIST(ACCESSOR_INFO_DECLARATION)
374 #undef ACCESSOR_INFO_DECLARATION 300 #undef ACCESSOR_INFO_DECLARATION
301 };
302
303 for (unsigned i = 0; i < arraysize(accessors); ++i) {
304 Add(accessors[i].address, accessors[i].name);
305 }
375 306
376 StubCache* stub_cache = isolate->stub_cache(); 307 StubCache* stub_cache = isolate->stub_cache();
377 308
378 // Stub cache tables 309 // Stub cache tables
379 Add(stub_cache->key_reference(StubCache::kPrimary).address(), 310 Add(stub_cache->key_reference(StubCache::kPrimary).address(),
380 STUB_CACHE_TABLE, 1, "StubCache::primary_->key"); 311 "StubCache::primary_->key");
381 Add(stub_cache->value_reference(StubCache::kPrimary).address(), 312 Add(stub_cache->value_reference(StubCache::kPrimary).address(),
382 STUB_CACHE_TABLE, 2, "StubCache::primary_->value"); 313 "StubCache::primary_->value");
383 Add(stub_cache->map_reference(StubCache::kPrimary).address(), 314 Add(stub_cache->map_reference(StubCache::kPrimary).address(),
384 STUB_CACHE_TABLE, 3, "StubCache::primary_->map"); 315 "StubCache::primary_->map");
385 Add(stub_cache->key_reference(StubCache::kSecondary).address(), 316 Add(stub_cache->key_reference(StubCache::kSecondary).address(),
386 STUB_CACHE_TABLE, 4, "StubCache::secondary_->key"); 317 "StubCache::secondary_->key");
387 Add(stub_cache->value_reference(StubCache::kSecondary).address(), 318 Add(stub_cache->value_reference(StubCache::kSecondary).address(),
388 STUB_CACHE_TABLE, 5, "StubCache::secondary_->value"); 319 "StubCache::secondary_->value");
389 Add(stub_cache->map_reference(StubCache::kSecondary).address(), 320 Add(stub_cache->map_reference(StubCache::kSecondary).address(),
390 STUB_CACHE_TABLE, 6, "StubCache::secondary_->map"); 321 "StubCache::secondary_->map");
391 322
392 // Runtime entries 323 // Runtime entries
393 Add(ExternalReference::delete_handle_scope_extensions(isolate).address(), 324 Add(ExternalReference::delete_handle_scope_extensions(isolate).address(),
394 RUNTIME_ENTRY, 1, "HandleScope::DeleteExtensions"); 325 "HandleScope::DeleteExtensions");
395 Add(ExternalReference::incremental_marking_record_write_function(isolate) 326 Add(ExternalReference::incremental_marking_record_write_function(isolate)
396 .address(), 327 .address(),
397 RUNTIME_ENTRY, 2, "IncrementalMarking::RecordWrite"); 328 "IncrementalMarking::RecordWrite");
398 Add(ExternalReference::store_buffer_overflow_function(isolate).address(), 329 Add(ExternalReference::store_buffer_overflow_function(isolate).address(),
399 RUNTIME_ENTRY, 3, "StoreBuffer::StoreBufferOverflow"); 330 "StoreBuffer::StoreBufferOverflow");
400 331
401 // Add a small set of deopt entry addresses to encoder without generating the 332 // Add a small set of deopt entry addresses to encoder without generating the
402 // deopt table code, which isn't possible at deserialization time. 333 // deopt table code, which isn't possible at deserialization time.
403 HandleScope scope(isolate); 334 HandleScope scope(isolate);
404 for (int entry = 0; entry < kDeoptTableSerializeEntryCount; ++entry) { 335 for (int entry = 0; entry < kDeoptTableSerializeEntryCount; ++entry) {
405 Address address = Deoptimizer::GetDeoptimizationEntry( 336 Address address = Deoptimizer::GetDeoptimizationEntry(
406 isolate, 337 isolate,
407 entry, 338 entry,
408 Deoptimizer::LAZY, 339 Deoptimizer::LAZY,
409 Deoptimizer::CALCULATE_ENTRY_ADDRESS); 340 Deoptimizer::CALCULATE_ENTRY_ADDRESS);
410 Add(address, LAZY_DEOPTIMIZATION, entry, "lazy_deopt"); 341 Add(address, "lazy_deopt");
411 } 342 }
412 } 343 }
413 344
414 345
415 ExternalReferenceEncoder::ExternalReferenceEncoder(Isolate* isolate) 346 ExternalReferenceEncoder::ExternalReferenceEncoder(Isolate* isolate)
416 : encodings_(HashMap::PointersMatch), 347 : map_(HashMap::PointersMatch) {
417 isolate_(isolate) { 348 ExternalReferenceTable* table = ExternalReferenceTable::instance(isolate);
418 ExternalReferenceTable* external_references = 349 for (int i = 0; i < table->size(); ++i) {
419 ExternalReferenceTable::instance(isolate_); 350 Address addr = table->address(i);
420 for (int i = 0; i < external_references->size(); ++i) { 351 if (addr == ExternalReferenceTable::NotAvailable()) continue;
421 Put(external_references->address(i), i); 352 // We expect no duplicate external references entries in the table.
353 DCHECK_NULL(map_.Lookup(addr, Hash(addr), false));
354 map_.Lookup(addr, Hash(addr), true)->value = reinterpret_cast<void*>(i);
422 } 355 }
423 } 356 }
424 357
425 358
426 uint32_t ExternalReferenceEncoder::Encode(Address key) const { 359 uint32_t ExternalReferenceEncoder::Encode(Address address) const {
427 int index = IndexOf(key); 360 DCHECK_NOT_NULL(address);
428 DCHECK(key == NULL || index >= 0); 361 HashMap::Entry* entry =
429 return index >= 0 ? 362 const_cast<HashMap&>(map_).Lookup(address, Hash(address), false);
430 ExternalReferenceTable::instance(isolate_)->code(index) : 0; 363 DCHECK_NOT_NULL(entry);
364 return static_cast<uint32_t>(reinterpret_cast<intptr_t>(entry->value));
431 } 365 }
432 366
433 367
434 const char* ExternalReferenceEncoder::NameOfAddress(Address key) const { 368 const char* ExternalReferenceEncoder::NameOfAddress(Isolate* isolate,
435 int index = IndexOf(key); 369 Address address) const {
436 return index >= 0 ? ExternalReferenceTable::instance(isolate_)->name(index) 370 HashMap::Entry* entry =
437 : "<unknown>"; 371 const_cast<HashMap&>(map_).Lookup(address, Hash(address), false);
372 if (entry == NULL) return "<unknown>";
373 uint32_t i = static_cast<uint32_t>(reinterpret_cast<intptr_t>(entry->value));
374 return ExternalReferenceTable::instance(isolate)->name(i);
438 } 375 }
439 376
440 377
441 int ExternalReferenceEncoder::IndexOf(Address key) const { 378 RootIndexMap::RootIndexMap(Isolate* isolate) : map_(HashMap::PointersMatch) {
442 if (key == NULL) return -1;
443 HashMap::Entry* entry =
444 const_cast<HashMap&>(encodings_).Lookup(key, Hash(key), false);
445 return entry == NULL
446 ? -1
447 : static_cast<int>(reinterpret_cast<intptr_t>(entry->value));
448 }
449
450
451 void ExternalReferenceEncoder::Put(Address key, int index) {
452 HashMap::Entry* entry = encodings_.Lookup(key, Hash(key), true);
453 entry->value = reinterpret_cast<void*>(index);
454 }
455
456
457 ExternalReferenceDecoder::ExternalReferenceDecoder(Isolate* isolate)
458 : encodings_(NewArray<Address*>(kTypeCodeCount)),
459 isolate_(isolate) {
460 ExternalReferenceTable* external_references =
461 ExternalReferenceTable::instance(isolate_);
462 for (int type = kFirstTypeCode; type < kTypeCodeCount; ++type) {
463 int max = external_references->max_id(type) + 1;
464 encodings_[type] = NewArray<Address>(max + 1);
465 }
466 for (int i = 0; i < external_references->size(); ++i) {
467 Put(external_references->code(i), external_references->address(i));
468 }
469 }
470
471
472 ExternalReferenceDecoder::~ExternalReferenceDecoder() {
473 for (int type = kFirstTypeCode; type < kTypeCodeCount; ++type) {
474 DeleteArray(encodings_[type]);
475 }
476 DeleteArray(encodings_);
477 }
478
479
480 RootIndexMap::RootIndexMap(Isolate* isolate) {
481 map_ = new HashMap(HashMap::PointersMatch);
482 Object** root_array = isolate->heap()->roots_array_start(); 379 Object** root_array = isolate->heap()->roots_array_start();
483 for (uint32_t i = 0; i < Heap::kStrongRootListLength; i++) { 380 for (uint32_t i = 0; i < Heap::kStrongRootListLength; i++) {
484 Object* root = root_array[i]; 381 Object* root = root_array[i];
485 if (root->IsHeapObject() && !isolate->heap()->InNewSpace(root)) { 382 if (root->IsHeapObject() && !isolate->heap()->InNewSpace(root)) {
486 HeapObject* heap_object = HeapObject::cast(root); 383 HeapObject* heap_object = HeapObject::cast(root);
487 HashMap::Entry* entry = LookupEntry(map_, heap_object, false); 384 HashMap::Entry* entry = LookupEntry(&map_, heap_object, false);
488 if (entry != NULL) { 385 if (entry != NULL) {
489 // Some are initialized to a previous value in the root list. 386 // Some are initialized to a previous value in the root list.
490 DCHECK_LT(GetValue(entry), i); 387 DCHECK_LT(GetValue(entry), i);
491 } else { 388 } else {
492 SetValue(LookupEntry(map_, heap_object, true), i); 389 SetValue(LookupEntry(&map_, heap_object, true), i);
493 } 390 }
494 } 391 }
495 } 392 }
496 } 393 }
497 394
498 395
499 class CodeAddressMap: public CodeEventLogger { 396 class CodeAddressMap: public CodeEventLogger {
500 public: 397 public:
501 explicit CodeAddressMap(Isolate* isolate) 398 explicit CodeAddressMap(Isolate* isolate)
502 : isolate_(isolate) { 399 : isolate_(isolate) {
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 high_water_[i] = reservations_[i][0].start; 540 high_water_[i] = reservations_[i][0].start;
644 } 541 }
645 return true; 542 return true;
646 } 543 }
647 544
648 545
649 void Deserializer::Initialize(Isolate* isolate) { 546 void Deserializer::Initialize(Isolate* isolate) {
650 DCHECK_NULL(isolate_); 547 DCHECK_NULL(isolate_);
651 DCHECK_NOT_NULL(isolate); 548 DCHECK_NOT_NULL(isolate);
652 isolate_ = isolate; 549 isolate_ = isolate;
653 DCHECK_NULL(external_reference_decoder_); 550 DCHECK_NULL(external_reference_table_);
654 external_reference_decoder_ = new ExternalReferenceDecoder(isolate); 551 external_reference_table_ = ExternalReferenceTable::instance(isolate);
552 CHECK_EQ(magic_number_,
553 SerializedData::ComputeMagicNumber(external_reference_table_));
655 } 554 }
656 555
657 556
658 void Deserializer::Deserialize(Isolate* isolate) { 557 void Deserializer::Deserialize(Isolate* isolate) {
659 Initialize(isolate); 558 Initialize(isolate);
660 if (!ReserveSpace()) V8::FatalProcessOutOfMemory("deserializing context"); 559 if (!ReserveSpace()) V8::FatalProcessOutOfMemory("deserializing context");
661 // No active threads. 560 // No active threads.
662 DCHECK_NULL(isolate_->thread_manager()->FirstThreadStateInUse()); 561 DCHECK_NULL(isolate_->thread_manager()->FirstThreadStateInUse());
663 // No active handles. 562 // No active handles.
664 DCHECK(isolate_->handle_scope_implementer()->blocks()->is_empty()); 563 DCHECK(isolate_->handle_scope_implementer()->blocks()->is_empty());
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 Object* root; 639 Object* root;
741 VisitPointer(&root); 640 VisitPointer(&root);
742 return Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(root)); 641 return Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(root));
743 } 642 }
744 } 643 }
745 644
746 645
747 Deserializer::~Deserializer() { 646 Deserializer::~Deserializer() {
748 // TODO(svenpanne) Re-enable this assertion when v8 initialization is fixed. 647 // TODO(svenpanne) Re-enable this assertion when v8 initialization is fixed.
749 // DCHECK(source_.AtEOF()); 648 // DCHECK(source_.AtEOF());
750 if (external_reference_decoder_) {
751 delete external_reference_decoder_;
752 external_reference_decoder_ = NULL;
753 }
754 attached_objects_.Dispose(); 649 attached_objects_.Dispose();
755 } 650 }
756 651
757 652
758 // This is called on the roots. It is the driver of the deserialization 653 // This is called on the roots. It is the driver of the deserialization
759 // process. It is also called on the body of each function. 654 // process. It is also called on the body of each function.
760 void Deserializer::VisitPointers(Object** start, Object** end) { 655 void Deserializer::VisitPointers(Object** start, Object** end) {
761 // The space must be new space. Any other space would cause ReadChunk to try 656 // The space must be new space. Any other space would cause ReadChunk to try
762 // to update the remembered using NULL as the address. 657 // to update the remembered using NULL as the address.
763 ReadData(start, end, NEW_SPACE, NULL); 658 ReadData(start, end, NEW_SPACE, NULL);
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
993 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \ 888 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
994 } else if (where == kPartialSnapshotCache) { \ 889 } else if (where == kPartialSnapshotCache) { \
995 int cache_index = source_.GetInt(); \ 890 int cache_index = source_.GetInt(); \
996 new_object = isolate->partial_snapshot_cache()->at(cache_index); \ 891 new_object = isolate->partial_snapshot_cache()->at(cache_index); \
997 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \ 892 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
998 } else if (where == kExternalReference) { \ 893 } else if (where == kExternalReference) { \
999 int skip = source_.GetInt(); \ 894 int skip = source_.GetInt(); \
1000 current = reinterpret_cast<Object**>( \ 895 current = reinterpret_cast<Object**>( \
1001 reinterpret_cast<Address>(current) + skip); \ 896 reinterpret_cast<Address>(current) + skip); \
1002 int reference_id = source_.GetInt(); \ 897 int reference_id = source_.GetInt(); \
1003 Address address = external_reference_decoder_->Decode(reference_id); \ 898 Address address = external_reference_table_->address(reference_id); \
1004 new_object = reinterpret_cast<Object*>(address); \ 899 new_object = reinterpret_cast<Object*>(address); \
1005 } else if (where == kBackref) { \ 900 } else if (where == kBackref) { \
1006 emit_write_barrier = (space_number == NEW_SPACE); \ 901 emit_write_barrier = (space_number == NEW_SPACE); \
1007 new_object = GetBackReferencedObject(data & kSpaceMask); \ 902 new_object = GetBackReferencedObject(data & kSpaceMask); \
1008 } else if (where == kBuiltin) { \ 903 } else if (where == kBuiltin) { \
1009 DCHECK(deserializing_user_code()); \ 904 DCHECK(deserializing_user_code()); \
1010 int builtin_id = source_.GetInt(); \ 905 int builtin_id = source_.GetInt(); \
1011 DCHECK_LE(0, builtin_id); \ 906 DCHECK_LE(0, builtin_id); \
1012 DCHECK_LT(builtin_id, Builtins::builtin_count); \ 907 DCHECK_LT(builtin_id, Builtins::builtin_count); \
1013 Builtins::Name name = static_cast<Builtins::Name>(builtin_id); \ 908 Builtins::Name name = static_cast<Builtins::Name>(builtin_id); \
(...skipping 1362 matching lines...) Expand 10 before | Expand all | Expand 10 after
2376 2271
2377 2272
2378 MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize( 2273 MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize(
2379 Isolate* isolate, ScriptData* cached_data, Handle<String> source) { 2274 Isolate* isolate, ScriptData* cached_data, Handle<String> source) {
2380 base::ElapsedTimer timer; 2275 base::ElapsedTimer timer;
2381 if (FLAG_profile_deserialization) timer.Start(); 2276 if (FLAG_profile_deserialization) timer.Start();
2382 2277
2383 HandleScope scope(isolate); 2278 HandleScope scope(isolate);
2384 2279
2385 SmartPointer<SerializedCodeData> scd( 2280 SmartPointer<SerializedCodeData> scd(
2386 SerializedCodeData::FromCachedData(cached_data, *source)); 2281 SerializedCodeData::FromCachedData(isolate, cached_data, *source));
2387 if (scd.is_empty()) { 2282 if (scd.is_empty()) {
2388 if (FLAG_profile_deserialization) PrintF("[Cached code failed check]\n"); 2283 if (FLAG_profile_deserialization) PrintF("[Cached code failed check]\n");
2389 DCHECK(cached_data->rejected()); 2284 DCHECK(cached_data->rejected());
2390 return MaybeHandle<SharedFunctionInfo>(); 2285 return MaybeHandle<SharedFunctionInfo>();
2391 } 2286 }
2392 2287
2393 // Eagerly expand string table to avoid allocations during deserialization. 2288 // Eagerly expand string table to avoid allocations during deserialization.
2394 StringTable::EnsureCapacityForDeserialization(isolate, 2289 StringTable::EnsureCapacityForDeserialization(isolate,
2395 scd->NumInternalizedStrings()); 2290 scd->NumInternalizedStrings());
2396 2291
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2454 const List<byte>& payload = ser.sink()->data(); 2349 const List<byte>& payload = ser.sink()->data();
2455 2350
2456 // Calculate sizes. 2351 // Calculate sizes.
2457 int reservation_size = reservations.length() * kInt32Size; 2352 int reservation_size = reservations.length() * kInt32Size;
2458 int size = kHeaderSize + reservation_size + payload.length(); 2353 int size = kHeaderSize + reservation_size + payload.length();
2459 2354
2460 // Allocate backing store and create result data. 2355 // Allocate backing store and create result data.
2461 AllocateData(size); 2356 AllocateData(size);
2462 2357
2463 // Set header values. 2358 // Set header values.
2359 SetMagicNumber(ser.isolate());
2464 SetHeaderValue(kCheckSumOffset, Version::Hash()); 2360 SetHeaderValue(kCheckSumOffset, Version::Hash());
2465 SetHeaderValue(kNumReservationsOffset, reservations.length()); 2361 SetHeaderValue(kNumReservationsOffset, reservations.length());
2466 SetHeaderValue(kPayloadLengthOffset, payload.length()); 2362 SetHeaderValue(kPayloadLengthOffset, payload.length());
2467 2363
2468 // Copy reservation chunk sizes. 2364 // Copy reservation chunk sizes.
2469 CopyBytes(data_ + kHeaderSize, reinterpret_cast<byte*>(reservations.begin()), 2365 CopyBytes(data_ + kHeaderSize, reinterpret_cast<byte*>(reservations.begin()),
2470 reservation_size); 2366 reservation_size);
2471 2367
2472 // Copy serialized data. 2368 // Copy serialized data.
2473 CopyBytes(data_ + kHeaderSize + reservation_size, payload.begin(), 2369 CopyBytes(data_ + kHeaderSize + reservation_size, payload.begin(),
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
2544 int num_stub_keys = stub_keys->length(); 2440 int num_stub_keys = stub_keys->length();
2545 int stub_keys_size = stub_keys->length() * kInt32Size; 2441 int stub_keys_size = stub_keys->length() * kInt32Size;
2546 int payload_offset = kHeaderSize + reservation_size + stub_keys_size; 2442 int payload_offset = kHeaderSize + reservation_size + stub_keys_size;
2547 int padded_payload_offset = POINTER_SIZE_ALIGN(payload_offset); 2443 int padded_payload_offset = POINTER_SIZE_ALIGN(payload_offset);
2548 int size = padded_payload_offset + payload.length(); 2444 int size = padded_payload_offset + payload.length();
2549 2445
2550 // Allocate backing store and create result data. 2446 // Allocate backing store and create result data.
2551 AllocateData(size); 2447 AllocateData(size);
2552 2448
2553 // Set header values. 2449 // Set header values.
2554 SetHeaderValue(kMagicNumberOffset, kMagicNumber); 2450 SetMagicNumber(cs.isolate());
2555 SetHeaderValue(kVersionHashOffset, Version::Hash()); 2451 SetHeaderValue(kVersionHashOffset, Version::Hash());
2556 SetHeaderValue(kSourceHashOffset, SourceHash(cs.source())); 2452 SetHeaderValue(kSourceHashOffset, SourceHash(cs.source()));
2557 SetHeaderValue(kCpuFeaturesOffset, 2453 SetHeaderValue(kCpuFeaturesOffset,
2558 static_cast<uint32_t>(CpuFeatures::SupportedFeatures())); 2454 static_cast<uint32_t>(CpuFeatures::SupportedFeatures()));
2559 SetHeaderValue(kFlagHashOffset, FlagList::Hash()); 2455 SetHeaderValue(kFlagHashOffset, FlagList::Hash());
2560 SetHeaderValue(kNumInternalizedStringsOffset, cs.num_internalized_strings()); 2456 SetHeaderValue(kNumInternalizedStringsOffset, cs.num_internalized_strings());
2561 SetHeaderValue(kNumReservationsOffset, reservations.length()); 2457 SetHeaderValue(kNumReservationsOffset, reservations.length());
2562 SetHeaderValue(kNumCodeStubKeysOffset, num_stub_keys); 2458 SetHeaderValue(kNumCodeStubKeysOffset, num_stub_keys);
2563 SetHeaderValue(kPayloadLengthOffset, payload.length()); 2459 SetHeaderValue(kPayloadLengthOffset, payload.length());
2564 2460
(...skipping 11 matching lines...) Expand all
2576 2472
2577 memset(data_ + payload_offset, 0, padded_payload_offset - payload_offset); 2473 memset(data_ + payload_offset, 0, padded_payload_offset - payload_offset);
2578 2474
2579 // Copy serialized data. 2475 // Copy serialized data.
2580 CopyBytes(data_ + padded_payload_offset, payload.begin(), 2476 CopyBytes(data_ + padded_payload_offset, payload.begin(),
2581 static_cast<size_t>(payload.length())); 2477 static_cast<size_t>(payload.length()));
2582 } 2478 }
2583 2479
2584 2480
2585 SerializedCodeData::SanityCheckResult SerializedCodeData::SanityCheck( 2481 SerializedCodeData::SanityCheckResult SerializedCodeData::SanityCheck(
2586 String* source) const { 2482 Isolate* isolate, String* source) const {
2587 uint32_t magic_number = GetHeaderValue(kMagicNumberOffset); 2483 uint32_t magic_number = GetMagicNumber();
2588 uint32_t version_hash = GetHeaderValue(kVersionHashOffset); 2484 uint32_t version_hash = GetHeaderValue(kVersionHashOffset);
2589 uint32_t source_hash = GetHeaderValue(kSourceHashOffset); 2485 uint32_t source_hash = GetHeaderValue(kSourceHashOffset);
2590 uint32_t cpu_features = GetHeaderValue(kCpuFeaturesOffset); 2486 uint32_t cpu_features = GetHeaderValue(kCpuFeaturesOffset);
2591 uint32_t flags_hash = GetHeaderValue(kFlagHashOffset); 2487 uint32_t flags_hash = GetHeaderValue(kFlagHashOffset);
2592 uint32_t c1 = GetHeaderValue(kChecksum1Offset); 2488 uint32_t c1 = GetHeaderValue(kChecksum1Offset);
2593 uint32_t c2 = GetHeaderValue(kChecksum2Offset); 2489 uint32_t c2 = GetHeaderValue(kChecksum2Offset);
2594 if (magic_number != kMagicNumber) return MAGIC_NUMBER_MISMATCH; 2490 if (magic_number != ComputeMagicNumber(isolate)) return MAGIC_NUMBER_MISMATCH;
2595 if (version_hash != Version::Hash()) return VERSION_MISMATCH; 2491 if (version_hash != Version::Hash()) return VERSION_MISMATCH;
2596 if (source_hash != SourceHash(source)) return SOURCE_MISMATCH; 2492 if (source_hash != SourceHash(source)) return SOURCE_MISMATCH;
2597 if (cpu_features != static_cast<uint32_t>(CpuFeatures::SupportedFeatures())) { 2493 if (cpu_features != static_cast<uint32_t>(CpuFeatures::SupportedFeatures())) {
2598 return CPU_FEATURES_MISMATCH; 2494 return CPU_FEATURES_MISMATCH;
2599 } 2495 }
2600 if (flags_hash != FlagList::Hash()) return FLAGS_MISMATCH; 2496 if (flags_hash != FlagList::Hash()) return FLAGS_MISMATCH;
2601 if (!Checksum(Payload()).Check(c1, c2)) return CHECKSUM_MISMATCH; 2497 if (!Checksum(Payload()).Check(c1, c2)) return CHECKSUM_MISMATCH;
2602 return CHECK_SUCCESS; 2498 return CHECK_SUCCESS;
2603 } 2499 }
2604 2500
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2644 const byte* start = data_ + kHeaderSize + reservations_size; 2540 const byte* start = data_ + kHeaderSize + reservations_size;
2645 return Vector<const uint32_t>(reinterpret_cast<const uint32_t*>(start), 2541 return Vector<const uint32_t>(reinterpret_cast<const uint32_t*>(start),
2646 GetHeaderValue(kNumCodeStubKeysOffset)); 2542 GetHeaderValue(kNumCodeStubKeysOffset));
2647 } 2543 }
2648 2544
2649 2545
2650 SerializedCodeData::SerializedCodeData(ScriptData* data) 2546 SerializedCodeData::SerializedCodeData(ScriptData* data)
2651 : SerializedData(const_cast<byte*>(data->data()), data->length()) {} 2547 : SerializedData(const_cast<byte*>(data->data()), data->length()) {}
2652 2548
2653 2549
2654 SerializedCodeData* SerializedCodeData::FromCachedData(ScriptData* cached_data, 2550 SerializedCodeData* SerializedCodeData::FromCachedData(Isolate* isolate,
2551 ScriptData* cached_data,
2655 String* source) { 2552 String* source) {
2656 DisallowHeapAllocation no_gc; 2553 DisallowHeapAllocation no_gc;
2657 SerializedCodeData* scd = new SerializedCodeData(cached_data); 2554 SerializedCodeData* scd = new SerializedCodeData(cached_data);
2658 SanityCheckResult r = scd->SanityCheck(source); 2555 SanityCheckResult r = scd->SanityCheck(isolate, source);
2659 if (r == CHECK_SUCCESS) return scd; 2556 if (r == CHECK_SUCCESS) return scd;
2660 cached_data->Reject(); 2557 cached_data->Reject();
2661 source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(r); 2558 source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(r);
2662 delete scd; 2559 delete scd;
2663 return NULL; 2560 return NULL;
2664 } 2561 }
2665 } } // namespace v8::internal 2562 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/serialize.h ('k') | test/cctest/test-serialize.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698