Revision: 22417
Author: [email protected]
Date: Wed Jul 16 06:59:14 2014 UTC
Log: Verify that source string matches serialized code.
[email protected], [email protected]
Review URL: https://codereview.chromium.org/394793002
http://code.google.com/p/v8/source/detail?r=22417
Modified:
/branches/bleeding_edge/src/assert-scope.h
/branches/bleeding_edge/src/compiler.cc
/branches/bleeding_edge/src/objects-inl.h
/branches/bleeding_edge/src/objects.cc
/branches/bleeding_edge/src/objects.h
/branches/bleeding_edge/src/serialize.cc
/branches/bleeding_edge/src/serialize.h
/branches/bleeding_edge/test/cctest/test-serialize.cc
=======================================
--- /branches/bleeding_edge/src/assert-scope.h Mon Jun 30 13:25:46 2014 UTC
+++ /branches/bleeding_edge/src/assert-scope.h Wed Jul 16 06:59:14 2014 UTC
@@ -28,7 +28,8 @@
JAVASCRIPT_EXECUTION_ASSERT,
JAVASCRIPT_EXECUTION_THROWS,
ALLOCATION_FAILURE_ASSERT,
- DEOPTIMIZATION_ASSERT
+ DEOPTIMIZATION_ASSERT,
+ COMPILATION_ASSERT
};
@@ -254,6 +255,13 @@
typedef PerIsolateAssertScopeDebugOnly<DEOPTIMIZATION_ASSERT, true>
AllowDeoptimization;
+// Scope to document where we do not expect deoptimization.
+typedef PerIsolateAssertScopeDebugOnly<COMPILATION_ASSERT, false>
+ DisallowCompilation;
+
+// Scope to introduce an exception to DisallowDeoptimization.
+typedef PerIsolateAssertScopeDebugOnly<COMPILATION_ASSERT, true>
+ AllowCompilation;
} } // namespace v8::internal
#endif // V8_ASSERT_SCOPE_H_
=======================================
--- /branches/bleeding_edge/src/compiler.cc Tue Jul 15 10:17:22 2014 UTC
+++ /branches/bleeding_edge/src/compiler.cc Wed Jul 16 06:59:14 2014 UTC
@@ -631,6 +631,7 @@
static bool CompileUnoptimizedCode(CompilationInfo* info) {
+ ASSERT(AllowCompilation::IsAllowed(info->isolate()));
ASSERT(info->function() != NULL);
if (!Rewriter::Rewrite(info)) return false;
if (!Scope::Analyze(info)) return false;
@@ -1196,6 +1197,7 @@
SmartPointer<CompilationInfo> info(new
CompilationInfoWithZone(function));
Isolate* isolate = info->isolate();
+ ASSERT(AllowCompilation::IsAllowed(isolate));
VMState<COMPILER> state(isolate);
ASSERT(!isolate->has_pending_exception());
PostponeInterruptsScope postpone(isolate);
=======================================
--- /branches/bleeding_edge/src/objects-inl.h Mon Jul 14 14:52:24 2014 UTC
+++ /branches/bleeding_edge/src/objects-inl.h Wed Jul 16 06:59:14 2014 UTC
@@ -6560,6 +6560,35 @@
if (!hasher.has_trivial_hash()) hasher.AddCharacters(chars, length);
return hasher.GetHashField();
}
+
+
+uint32_t IteratingStringHasher::Hash(String* string, uint32_t seed) {
+ IteratingStringHasher hasher(string->length(), seed);
+ // Nothing to do.
+ if (hasher.has_trivial_hash()) return hasher.GetHashField();
+ ConsString* cons_string = String::VisitFlat(&hasher, string);
+ // The string was flat.
+ if (cons_string == NULL) return hasher.GetHashField();
+ // This is a ConsString, iterate across it.
+ ConsStringIteratorOp op(cons_string);
+ int offset;
+ while (NULL != (string = op.Next(&offset))) {
+ String::VisitFlat(&hasher, string, offset);
+ }
+ return hasher.GetHashField();
+}
+
+
+void IteratingStringHasher::VisitOneByteString(const uint8_t* chars,
+ int length) {
+ AddCharacters(chars, length);
+}
+
+
+void IteratingStringHasher::VisitTwoByteString(const uint16_t* chars,
+ int length) {
+ AddCharacters(chars, length);
+}
bool Name::AsArrayIndex(uint32_t* index) {
=======================================
--- /branches/bleeding_edge/src/objects.cc Tue Jul 15 10:51:12 2014 UTC
+++ /branches/bleeding_edge/src/objects.cc Wed Jul 16 06:59:14 2014 UTC
@@ -9332,38 +9332,6 @@
}
-class IteratingStringHasher: public StringHasher {
- public:
- static inline uint32_t Hash(String* string, uint32_t seed) {
- IteratingStringHasher hasher(string->length(), seed);
- // Nothing to do.
- if (hasher.has_trivial_hash()) return hasher.GetHashField();
- ConsString* cons_string = String::VisitFlat(&hasher, string);
- // The string was flat.
- if (cons_string == NULL) return hasher.GetHashField();
- // This is a ConsString, iterate across it.
- ConsStringIteratorOp op(cons_string);
- int offset;
- while (NULL != (string = op.Next(&offset))) {
- String::VisitFlat(&hasher, string, offset);
- }
- return hasher.GetHashField();
- }
- inline void VisitOneByteString(const uint8_t* chars, int length) {
- AddCharacters(chars, length);
- }
- inline void VisitTwoByteString(const uint16_t* chars, int length) {
- AddCharacters(chars, length);
- }
-
- private:
- inline IteratingStringHasher(int len, uint32_t seed)
- : StringHasher(len, seed) {
- }
- DISALLOW_COPY_AND_ASSIGN(IteratingStringHasher);
-};
-
-
uint32_t String::ComputeAndSetHash() {
// Should only be called if hash code has not yet been computed.
ASSERT(!HasHashCode());
=======================================
--- /branches/bleeding_edge/src/objects.h Tue Jul 15 09:19:22 2014 UTC
+++ /branches/bleeding_edge/src/objects.h Wed Jul 16 06:59:14 2014 UTC
@@ -8854,6 +8854,19 @@
};
+class IteratingStringHasher : public StringHasher {
+ public:
+ static inline uint32_t Hash(String* string, uint32_t seed);
+ inline void VisitOneByteString(const uint8_t* chars, int length);
+ inline void VisitTwoByteString(const uint16_t* chars, int length);
+
+ private:
+ inline IteratingStringHasher(int len, uint32_t seed)
+ : StringHasher(len, seed) {}
+ DISALLOW_COPY_AND_ASSIGN(IteratingStringHasher);
+};
+
+
// The characteristics of a string are stored in its map. Retrieving these
// few bits of information is moderately expensive, involving two memory
// loads where the second is dependent on the first. To improve efficiency
=======================================
--- /branches/bleeding_edge/src/serialize.cc Tue Jul 15 11:01:03 2014 UTC
+++ /branches/bleeding_edge/src/serialize.cc Wed Jul 16 06:59:14 2014 UTC
@@ -13,6 +13,7 @@
#include "src/global-handles.h"
#include "src/ic-inl.h"
#include "src/natives.h"
+#include "src/objects.h"
#include "src/runtime.h"
#include "src/serialize.h"
#include "src/snapshot.h"
@@ -1993,7 +1994,7 @@
Handle<SharedFunctionInfo> CodeSerializer::Deserialize(Isolate* isolate,
ScriptData* data,
Handle<String>
source) {
- SerializedCodeData scd(data);
+ SerializedCodeData scd(data, *source);
SnapshotByteSource payload(scd.Payload(), scd.PayloadLength());
Deserializer deserializer(&payload);
STATIC_ASSERT(NEW_SPACE == 0);
@@ -2017,6 +2018,7 @@
SerializedCodeData::SerializedCodeData(List<byte>* payload,
CodeSerializer* cs)
: owns_script_data_(true) {
+ DisallowHeapAllocation no_gc;
int data_length = payload->length() + kHeaderEntries * kIntSize;
byte* data = NewArray<byte>(data_length);
ASSERT(IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment));
@@ -2024,7 +2026,7 @@
static_cast<size_t>(payload->length()));
script_data_ = new ScriptData(data, data_length);
script_data_->AcquireDataOwnership();
- SetHeaderValue(kVersionHashOffset, Version::Hash());
+ SetHeaderValue(kCheckSumOffset, CheckSum(cs->source()));
STATIC_ASSERT(NEW_SPACE == 0);
for (int i = NEW_SPACE; i <= PROPERTY_CELL_SPACE; i++) {
SetHeaderValue(kReservationsOffset + i,
cs->CurrentAllocationAddress(i));
@@ -2032,8 +2034,18 @@
}
-bool SerializedCodeData::IsSane() {
- return GetHeaderValue(kVersionHashOffset) == Version::Hash() &&
+bool SerializedCodeData::IsSane(String* source) {
+ return GetHeaderValue(kCheckSumOffset) == CheckSum(source) &&
PayloadLength() >= SharedFunctionInfo::kSize;
}
+
+
+int SerializedCodeData::CheckSum(String* string) {
+ int checksum = Version::Hash();
+#ifdef DEBUG
+ uint32_t seed = static_cast<uint32_t>(checksum);
+ checksum = static_cast<int>(IteratingStringHasher::Hash(string, seed));
+#endif // DEBUG
+ return checksum;
+}
} } // namespace v8::internal
=======================================
--- /branches/bleeding_edge/src/serialize.h Tue Jul 15 11:01:03 2014 UTC
+++ /branches/bleeding_edge/src/serialize.h Wed Jul 16 06:59:14 2014 UTC
@@ -590,6 +590,11 @@
static const int kSourceObjectIndex = 0;
+ String* source() {
+ ASSERT(!AllowHeapAllocation::IsAllowed());
+ return source_;
+ }
+
private:
void SerializeBuiltin(Code* builtin, HowToCode how_to_code,
WhereToPoint where_to_point, int skip);
@@ -606,9 +611,10 @@
class SerializedCodeData {
public:
// Used by when consuming.
- explicit SerializedCodeData(ScriptData* data)
+ explicit SerializedCodeData(ScriptData* data, String* source)
: script_data_(data), owns_script_data_(false) {
- CHECK(IsSane());
+ DisallowHeapAllocation no_gc;
+ CHECK(IsSane(source));
}
// Used when producing.
@@ -649,12 +655,14 @@
return reinterpret_cast<const int*>(script_data_->data())[offset];
}
- bool IsSane();
+ bool IsSane(String* source);
+
+ int CheckSum(String* source);
// The data header consists of int-sized entries:
// [0] version hash
// [1..7] reservation sizes for spaces from NEW_SPACE to
PROPERTY_CELL_SPACE.
- static const int kVersionHashOffset = 0;
+ static const int kCheckSumOffset = 0;
static const int kReservationsOffset = 1;
static const int kHeaderEntries = 8;
=======================================
--- /branches/bleeding_edge/test/cctest/test-serialize.cc Tue Jul 15
10:17:22 2014 UTC
+++ /branches/bleeding_edge/test/cctest/test-serialize.cc Wed Jul 16
06:59:14 2014 UTC
@@ -32,6 +32,7 @@
#include "src/v8.h"
#include "src/bootstrapper.h"
+#include "src/compilation-cache.h"
#include "src/debug.h"
#include "src/ic-inl.h"
#include "src/natives.h"
@@ -678,36 +679,41 @@
TEST(SerializeToplevelOnePlusOne) {
FLAG_serialize_toplevel = true;
LocalContext context;
+ Isolate* isolate = CcTest::i_isolate();
+ isolate->compilation_cache()->Disable(); // Disable same-isolate code
cache.
+
v8::HandleScope scope(CcTest::isolate());
- const char* source1 = "1 + 1";
- const char* source2 = "1 + 2"; // Use alternate string to verify
caching.
+ const char* source = "1 + 1";
- Isolate* isolate = CcTest::i_isolate();
- Handle<String> source1_string = isolate->factory()
-
->NewStringFromUtf8(CStrVector(source1))
- .ToHandleChecked();
-
- Handle<String> source2_string = isolate->factory()
-
->NewStringFromUtf8(CStrVector(source2))
- .ToHandleChecked();
+ Handle<String> orig_source = isolate->factory()
+ ->NewStringFromUtf8(CStrVector(source))
+ .ToHandleChecked();
+ Handle<String> copy_source = isolate->factory()
+ ->NewStringFromUtf8(CStrVector(source))
+ .ToHandleChecked();
+ CHECK(!orig_source.is_identical_to(copy_source));
+ CHECK(orig_source->Equals(*copy_source));
ScriptData* cache = NULL;
Handle<SharedFunctionInfo> orig =
- Compiler::CompileScript(source1_string, Handle<String>(), 0, 0,
false,
+ Compiler::CompileScript(orig_source, Handle<String>(), 0, 0, false,
Handle<Context>(isolate->native_context()),
NULL,
&cache, PRODUCE_CACHED_DATA,
NOT_NATIVES_CODE);
int builtins_count = CountBuiltins();
- Handle<SharedFunctionInfo> copy =
- Compiler::CompileScript(source2_string, Handle<String>(), 0, 0,
false,
- Handle<Context>(isolate->native_context()),
NULL,
- &cache, CONSUME_CACHED_DATA,
NOT_NATIVES_CODE);
-
+ Handle<SharedFunctionInfo> copy;
+ {
+ DisallowCompilation no_compile_expected(isolate);
+ copy = Compiler::CompileScript(copy_source, Handle<String>(), 0, 0,
false,
+
Handle<Context>(isolate->native_context()),
+ NULL, &cache, CONSUME_CACHED_DATA,
+ NOT_NATIVES_CODE);
+ }
CHECK_NE(*orig, *copy);
- CHECK(Script::cast(copy->script())->source() == *source2_string);
+ CHECK(Script::cast(copy->script())->source() == *copy_source);
Handle<JSFunction> copy_fun =
isolate->factory()->NewFunctionFromSharedFunctionInfo(
@@ -726,24 +732,27 @@
TEST(SerializeToplevelInternalizedString) {
FLAG_serialize_toplevel = true;
LocalContext context;
+ Isolate* isolate = CcTest::i_isolate();
+ isolate->compilation_cache()->Disable(); // Disable same-isolate code
cache.
+
v8::HandleScope scope(CcTest::isolate());
- const char* source1 = "'string1'";
- const char* source2 = "'string2'"; // Use alternate string to verify
caching.
+ const char* source = "'string1'";
- Isolate* isolate = CcTest::i_isolate();
- Handle<String> source1_string = isolate->factory()
-
->NewStringFromUtf8(CStrVector(source1))
- .ToHandleChecked();
+ Handle<String> orig_source = isolate->factory()
+ ->NewStringFromUtf8(CStrVector(source))
+ .ToHandleChecked();
+ Handle<String> copy_source = isolate->factory()
+ ->NewStringFromUtf8(CStrVector(source))
+ .ToHandleChecked();
+ CHECK(!orig_source.is_identical_to(copy_source));
+ CHECK(orig_source->Equals(*copy_source));
- Handle<String> source2_string = isolate->factory()
-
->NewStringFromUtf8(CStrVector(source2))
- .ToHandleChecked();
Handle<JSObject> global(isolate->context()->global_object());
ScriptData* cache = NULL;
Handle<SharedFunctionInfo> orig =
- Compiler::CompileScript(source1_string, Handle<String>(), 0, 0,
false,
+ Compiler::CompileScript(orig_source, Handle<String>(), 0, 0, false,
Handle<Context>(isolate->native_context()),
NULL,
&cache, PRODUCE_CACHED_DATA,
NOT_NATIVES_CODE);
Handle<JSFunction> orig_fun =
@@ -755,12 +764,16 @@
int builtins_count = CountBuiltins();
- Handle<SharedFunctionInfo> copy =
- Compiler::CompileScript(source2_string, Handle<String>(), 0, 0,
false,
- Handle<Context>(isolate->native_context()),
NULL,
- &cache, CONSUME_CACHED_DATA,
NOT_NATIVES_CODE);
+ Handle<SharedFunctionInfo> copy;
+ {
+ DisallowCompilation no_compile_expected(isolate);
+ copy = Compiler::CompileScript(copy_source, Handle<String>(), 0, 0,
false,
+
Handle<Context>(isolate->native_context()),
+ NULL, &cache, CONSUME_CACHED_DATA,
+ NOT_NATIVES_CODE);
+ }
CHECK_NE(*orig, *copy);
- CHECK(Script::cast(copy->script())->source() == *source2_string);
+ CHECK(Script::cast(copy->script())->source() == *copy_source);
Handle<JSFunction> copy_fun =
isolate->factory()->NewFunctionFromSharedFunctionInfo(
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.