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.

Reply via email to