OLD | NEW |
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 2139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2150 offset); | 2150 offset); |
2151 } | 2151 } |
2152 | 2152 |
2153 | 2153 |
2154 void Serializer::Pad() { | 2154 void Serializer::Pad() { |
2155 // The non-branching GetInt will read up to 3 bytes too far, so we need | 2155 // The non-branching GetInt will read up to 3 bytes too far, so we need |
2156 // to pad the snapshot to make sure we don't read over the end. | 2156 // to pad the snapshot to make sure we don't read over the end. |
2157 for (unsigned i = 0; i < sizeof(int32_t) - 1; i++) { | 2157 for (unsigned i = 0; i < sizeof(int32_t) - 1; i++) { |
2158 sink_->Put(kNop, "Padding"); | 2158 sink_->Put(kNop, "Padding"); |
2159 } | 2159 } |
| 2160 // Pad up to pointer size for checksum. |
| 2161 while (!IsAligned(sink_->Position(), kPointerAlignment)) { |
| 2162 sink_->Put(kNop, "Padding"); |
| 2163 } |
2160 } | 2164 } |
2161 | 2165 |
2162 | 2166 |
2163 void Serializer::InitializeCodeAddressMap() { | 2167 void Serializer::InitializeCodeAddressMap() { |
2164 isolate_->InitializeLoggingAndCounters(); | 2168 isolate_->InitializeLoggingAndCounters(); |
2165 code_address_map_ = new CodeAddressMap(isolate_); | 2169 code_address_map_ = new CodeAddressMap(isolate_); |
2166 } | 2170 } |
2167 | 2171 |
2168 | 2172 |
2169 ScriptData* CodeSerializer::Serialize(Isolate* isolate, | 2173 ScriptData* CodeSerializer::Serialize(Isolate* isolate, |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2475 | 2479 |
2476 Vector<const byte> SnapshotData::Payload() const { | 2480 Vector<const byte> SnapshotData::Payload() const { |
2477 int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size; | 2481 int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size; |
2478 const byte* payload = data_ + kHeaderSize + reservations_size; | 2482 const byte* payload = data_ + kHeaderSize + reservations_size; |
2479 int length = GetHeaderValue(kPayloadLengthOffset); | 2483 int length = GetHeaderValue(kPayloadLengthOffset); |
2480 DCHECK_EQ(data_ + size_, payload + length); | 2484 DCHECK_EQ(data_ + size_, payload + length); |
2481 return Vector<const byte>(payload, length); | 2485 return Vector<const byte>(payload, length); |
2482 } | 2486 } |
2483 | 2487 |
2484 | 2488 |
| 2489 class Checksum { |
| 2490 public: |
| 2491 explicit Checksum(Vector<const byte> payload) { |
| 2492 // Fletcher's checksum. Modified to reduce 64-bit sums to 32-bit. |
| 2493 uintptr_t a = 1; |
| 2494 uintptr_t b = 0; |
| 2495 const uintptr_t* cur = reinterpret_cast<const uintptr_t*>(payload.start()); |
| 2496 DCHECK(IsAligned(payload.length(), kIntptrSize)); |
| 2497 const uintptr_t* end = cur + payload.length() / kIntptrSize; |
| 2498 while (cur < end) { |
| 2499 // Unsigned overflow expected and intended. |
| 2500 a += *cur++; |
| 2501 b += a; |
| 2502 } |
| 2503 #if V8_HOST_ARCH_64_BIT |
| 2504 a ^= a >> 32; |
| 2505 b ^= b >> 32; |
| 2506 #endif // V8_HOST_ARCH_64_BIT |
| 2507 a_ = static_cast<uint32_t>(a); |
| 2508 b_ = static_cast<uint32_t>(b); |
| 2509 } |
| 2510 |
| 2511 bool Check(uint32_t a, uint32_t b) const { return a == a_ && b == b_; } |
| 2512 |
| 2513 uint32_t a() const { return a_; } |
| 2514 uint32_t b() const { return b_; } |
| 2515 |
| 2516 private: |
| 2517 uint32_t a_; |
| 2518 uint32_t b_; |
| 2519 |
| 2520 DISALLOW_COPY_AND_ASSIGN(Checksum); |
| 2521 }; |
| 2522 |
| 2523 |
2485 SerializedCodeData::SerializedCodeData(const List<byte>& payload, | 2524 SerializedCodeData::SerializedCodeData(const List<byte>& payload, |
2486 const CodeSerializer& cs) { | 2525 const CodeSerializer& cs) { |
2487 DisallowHeapAllocation no_gc; | 2526 DisallowHeapAllocation no_gc; |
2488 const List<uint32_t>* stub_keys = cs.stub_keys(); | 2527 const List<uint32_t>* stub_keys = cs.stub_keys(); |
2489 | 2528 |
2490 List<Reservation> reservations; | 2529 List<Reservation> reservations; |
2491 cs.EncodeReservations(&reservations); | 2530 cs.EncodeReservations(&reservations); |
2492 | 2531 |
2493 // Calculate sizes. | 2532 // Calculate sizes. |
2494 int reservation_size = reservations.length() * kInt32Size; | 2533 int reservation_size = reservations.length() * kInt32Size; |
2495 int num_stub_keys = stub_keys->length(); | 2534 int num_stub_keys = stub_keys->length(); |
2496 int stub_keys_size = stub_keys->length() * kInt32Size; | 2535 int stub_keys_size = stub_keys->length() * kInt32Size; |
2497 int size = kHeaderSize + reservation_size + stub_keys_size + payload.length(); | 2536 int size = kHeaderSize + reservation_size + stub_keys_size + payload.length(); |
2498 | 2537 |
2499 // Allocate backing store and create result data. | 2538 // Allocate backing store and create result data. |
2500 AllocateData(size); | 2539 AllocateData(size); |
2501 | 2540 |
2502 // Set header values. | 2541 // Set header values. |
2503 SetHeaderValue(kVersionHashOffset, Version::Hash()); | 2542 SetHeaderValue(kVersionHashOffset, Version::Hash()); |
2504 SetHeaderValue(kSourceHashOffset, SourceHash(cs.source())); | 2543 SetHeaderValue(kSourceHashOffset, SourceHash(cs.source())); |
2505 SetHeaderValue(kCpuFeaturesOffset, | 2544 SetHeaderValue(kCpuFeaturesOffset, |
2506 static_cast<uint32_t>(CpuFeatures::SupportedFeatures())); | 2545 static_cast<uint32_t>(CpuFeatures::SupportedFeatures())); |
2507 SetHeaderValue(kFlagHashOffset, FlagList::Hash()); | 2546 SetHeaderValue(kFlagHashOffset, FlagList::Hash()); |
2508 SetHeaderValue(kNumInternalizedStringsOffset, cs.num_internalized_strings()); | 2547 SetHeaderValue(kNumInternalizedStringsOffset, cs.num_internalized_strings()); |
2509 SetHeaderValue(kReservationsOffset, reservations.length()); | 2548 SetHeaderValue(kReservationsOffset, reservations.length()); |
2510 SetHeaderValue(kNumCodeStubKeysOffset, num_stub_keys); | 2549 SetHeaderValue(kNumCodeStubKeysOffset, num_stub_keys); |
2511 SetHeaderValue(kPayloadLengthOffset, payload.length()); | 2550 SetHeaderValue(kPayloadLengthOffset, payload.length()); |
2512 | 2551 |
| 2552 Checksum checksum(payload.ToConstVector()); |
| 2553 SetHeaderValue(kChecksum1Offset, checksum.a()); |
| 2554 SetHeaderValue(kChecksum2Offset, checksum.b()); |
| 2555 |
2513 // Copy reservation chunk sizes. | 2556 // Copy reservation chunk sizes. |
2514 CopyBytes(data_ + kHeaderSize, reinterpret_cast<byte*>(reservations.begin()), | 2557 CopyBytes(data_ + kHeaderSize, reinterpret_cast<byte*>(reservations.begin()), |
2515 reservation_size); | 2558 reservation_size); |
2516 | 2559 |
2517 // Copy code stub keys. | 2560 // Copy code stub keys. |
2518 CopyBytes(data_ + kHeaderSize + reservation_size, | 2561 CopyBytes(data_ + kHeaderSize + reservation_size, |
2519 reinterpret_cast<byte*>(stub_keys->begin()), stub_keys_size); | 2562 reinterpret_cast<byte*>(stub_keys->begin()), stub_keys_size); |
2520 | 2563 |
2521 // Copy serialized data. | 2564 // Copy serialized data. |
2522 CopyBytes(data_ + kHeaderSize + reservation_size + stub_keys_size, | 2565 CopyBytes(data_ + kHeaderSize + reservation_size + stub_keys_size, |
2523 payload.begin(), static_cast<size_t>(payload.length())); | 2566 payload.begin(), static_cast<size_t>(payload.length())); |
2524 } | 2567 } |
2525 | 2568 |
2526 | 2569 |
2527 bool SerializedCodeData::IsSane(String* source) { | 2570 bool SerializedCodeData::IsSane(String* source) const { |
2528 return GetHeaderValue(kVersionHashOffset) == Version::Hash() && | 2571 return GetHeaderValue(kVersionHashOffset) == Version::Hash() && |
2529 GetHeaderValue(kSourceHashOffset) == SourceHash(source) && | 2572 GetHeaderValue(kSourceHashOffset) == SourceHash(source) && |
2530 GetHeaderValue(kCpuFeaturesOffset) == | 2573 GetHeaderValue(kCpuFeaturesOffset) == |
2531 static_cast<uint32_t>(CpuFeatures::SupportedFeatures()) && | 2574 static_cast<uint32_t>(CpuFeatures::SupportedFeatures()) && |
2532 GetHeaderValue(kFlagHashOffset) == FlagList::Hash() && | 2575 GetHeaderValue(kFlagHashOffset) == FlagList::Hash() && |
2533 Payload().length() >= SharedFunctionInfo::kSize; | 2576 Checksum(Payload()).Check(GetHeaderValue(kChecksum1Offset), |
| 2577 GetHeaderValue(kChecksum2Offset)); |
2534 } | 2578 } |
2535 | 2579 |
2536 | 2580 |
2537 // Return ScriptData object and relinquish ownership over it to the caller. | 2581 // Return ScriptData object and relinquish ownership over it to the caller. |
2538 ScriptData* SerializedCodeData::GetScriptData() { | 2582 ScriptData* SerializedCodeData::GetScriptData() { |
2539 DCHECK(owns_data_); | 2583 DCHECK(owns_data_); |
2540 ScriptData* result = new ScriptData(data_, size_); | 2584 ScriptData* result = new ScriptData(data_, size_); |
2541 result->AcquireDataOwnership(); | 2585 result->AcquireDataOwnership(); |
2542 owns_data_ = false; | 2586 owns_data_ = false; |
2543 data_ = NULL; | 2587 data_ = NULL; |
(...skipping 24 matching lines...) Expand all Loading... |
2568 return GetHeaderValue(kNumInternalizedStringsOffset); | 2612 return GetHeaderValue(kNumInternalizedStringsOffset); |
2569 } | 2613 } |
2570 | 2614 |
2571 Vector<const uint32_t> SerializedCodeData::CodeStubKeys() const { | 2615 Vector<const uint32_t> SerializedCodeData::CodeStubKeys() const { |
2572 int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size; | 2616 int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size; |
2573 const byte* start = data_ + kHeaderSize + reservations_size; | 2617 const byte* start = data_ + kHeaderSize + reservations_size; |
2574 return Vector<const uint32_t>(reinterpret_cast<const uint32_t*>(start), | 2618 return Vector<const uint32_t>(reinterpret_cast<const uint32_t*>(start), |
2575 GetHeaderValue(kNumCodeStubKeysOffset)); | 2619 GetHeaderValue(kNumCodeStubKeysOffset)); |
2576 } | 2620 } |
2577 } } // namespace v8::internal | 2621 } } // namespace v8::internal |
OLD | NEW |