Upgrade v8 to 1.3.15
authorRyan Dahl <ry@tinyclouds.org>
Wed, 7 Oct 2009 14:02:34 +0000 (16:02 +0200)
committerRyan Dahl <ry@tinyclouds.org>
Wed, 7 Oct 2009 14:02:34 +0000 (16:02 +0200)
deps/v8/ChangeLog
deps/v8/src/debug.cc
deps/v8/src/heap.cc
deps/v8/src/log.cc
deps/v8/src/objects-inl.h
deps/v8/src/objects.h
deps/v8/src/version.cc
deps/v8/test/cctest/test-log.cc
deps/v8/test/mjsunit/invalid-source-element.js [new file with mode: 0644]

index 88c34f9..d07c458 100644 (file)
@@ -1,3 +1,11 @@
+2009-10-07: Version 1.3.15
+
+        Expand the maximum size of the code space to 512MB for 64-bit mode.
+
+        Fixed a crash bug happening when starting profiling (issue
+        http://crbug.com/23768).
+
+
 2009-10-07: Version 1.3.14
 
         Added GetRealNamedProperty to the API to lookup real properties
index ec658d6..4f89f92 100644 (file)
@@ -1677,22 +1677,6 @@ void Debug::ClearMirrorCache() {
 }
 
 
-// If an object given is an external string, check that the underlying
-// resource is accessible. For other kinds of objects, always return true.
-static bool IsExternalStringValid(Object* str) {
-  if (!str->IsString() || !StringShape(String::cast(str)).IsExternal()) {
-    return true;
-  }
-  if (String::cast(str)->IsAsciiRepresentation()) {
-    return ExternalAsciiString::cast(str)->resource() != NULL;
-  } else if (String::cast(str)->IsTwoByteRepresentation()) {
-    return ExternalTwoByteString::cast(str)->resource() != NULL;
-  } else {
-    return true;
-  }
-}
-
-
 void Debug::CreateScriptCache() {
   HandleScope scope;
 
@@ -1711,7 +1695,7 @@ void Debug::CreateScriptCache() {
   while (iterator.has_next()) {
     HeapObject* obj = iterator.next();
     ASSERT(obj != NULL);
-    if (obj->IsScript() && IsExternalStringValid(Script::cast(obj)->source())) {
+    if (obj->IsScript() && Script::cast(obj)->HasValidSource()) {
       script_cache_->Add(Handle<Script>(Script::cast(obj)));
       count++;
     }
index dcc25a3..0295a99 100644 (file)
@@ -82,7 +82,7 @@ size_t Heap::code_range_size_ = 0;
 int Heap::semispace_size_  = 16*MB;
 int Heap::old_generation_size_ = 1*GB;
 int Heap::initial_semispace_size_ = 1*MB;
-size_t Heap::code_range_size_ = 256*MB;
+size_t Heap::code_range_size_ = 512*MB;
 #else
 int Heap::semispace_size_  = 8*MB;
 int Heap::old_generation_size_ = 512*MB;
index d225c3b..1c82f85 100644 (file)
@@ -1070,37 +1070,33 @@ int Logger::GetLogLines(int from_pos, char* dest_buf, int max_size) {
 }
 
 
-void Logger::LogCompiledFunctions() {
-  HandleScope scope;
-  Handle<SharedFunctionInfo>* sfis = NULL;
+static int EnumerateCompiledFunctions(Handle<SharedFunctionInfo>* sfis) {
+  AssertNoAllocation no_alloc;
   int compiled_funcs_count = 0;
-
-  {
-    AssertNoAllocation no_alloc;
-
-    HeapIterator iterator;
-    while (iterator.has_next()) {
-      HeapObject* obj = iterator.next();
-      ASSERT(obj != NULL);
-      if (obj->IsSharedFunctionInfo()
-          && SharedFunctionInfo::cast(obj)->is_compiled()) {
-        ++compiled_funcs_count;
-      }
+  HeapIterator iterator;
+  while (iterator.has_next()) {
+    HeapObject* obj = iterator.next();
+    ASSERT(obj != NULL);
+    if (!obj->IsSharedFunctionInfo()) continue;
+    SharedFunctionInfo* sfi = SharedFunctionInfo::cast(obj);
+    if (sfi->is_compiled()
+        && (!sfi->script()->IsScript()
+            || Script::cast(sfi->script())->HasValidSource())) {
+      if (sfis != NULL)
+        sfis[compiled_funcs_count] = Handle<SharedFunctionInfo>(sfi);
+      ++compiled_funcs_count;
     }
+  }
+  return compiled_funcs_count;
+}
 
-    sfis = NewArray< Handle<SharedFunctionInfo> >(compiled_funcs_count);
-    iterator.reset();
 
-    int i = 0;
-    while (iterator.has_next()) {
-      HeapObject* obj = iterator.next();
-      ASSERT(obj != NULL);
-      if (obj->IsSharedFunctionInfo()
-          && SharedFunctionInfo::cast(obj)->is_compiled()) {
-        sfis[i++] = Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(obj));
-      }
-    }
-  }
+void Logger::LogCompiledFunctions() {
+  HandleScope scope;
+  const int compiled_funcs_count = EnumerateCompiledFunctions(NULL);
+  Handle<SharedFunctionInfo>* sfis =
+      NewArray< Handle<SharedFunctionInfo> >(compiled_funcs_count);
+  EnumerateCompiledFunctions(sfis);
 
   // During iteration, there can be heap allocation due to
   // GetScriptLineNumber call.
index 29b886d..22e12ac 100644 (file)
@@ -2361,6 +2361,20 @@ INT_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
               kThisPropertyAssignmentsCountOffset)
 
 
+bool Script::HasValidSource() {
+  Object* src = this->source();
+  if (!src->IsString()) return true;
+  String* src_str = String::cast(src);
+  if (!StringShape(src_str).IsExternal()) return true;
+  if (src_str->IsAsciiRepresentation()) {
+    return ExternalAsciiString::cast(src)->resource() != NULL;
+  } else if (src_str->IsTwoByteRepresentation()) {
+    return ExternalTwoByteString::cast(src)->resource() != NULL;
+  }
+  return true;
+}
+
+
 void SharedFunctionInfo::DontAdaptArguments() {
   ASSERT(code()->kind() == Code::BUILTIN);
   set_formal_parameter_count(kDontAdaptArgumentsSentinel);
index e9430f5..c78c73b 100644 (file)
@@ -2998,6 +2998,10 @@ class Script: public Struct {
 
   static inline Script* cast(Object* obj);
 
+  // If script source is an external string, check that the underlying
+  // resource is accessible. Otherwise, always return true.
+  inline bool HasValidSource();
+
 #ifdef DEBUG
   void ScriptPrint();
   void ScriptVerify();
index 28815cc..fdbcb58 100644 (file)
@@ -34,7 +34,7 @@
 // cannot be changed without changing the SCons build script.
 #define MAJOR_VERSION     1
 #define MINOR_VERSION     3
-#define BUILD_NUMBER      14
+#define BUILD_NUMBER      15
 #define PATCH_LEVEL       0
 #define CANDIDATE_VERSION false
 
index 65ab50a..3983215 100644 (file)
@@ -430,6 +430,50 @@ TEST(ProfMultipleThreads) {
 #endif  // __linux__
 
 
+// Test for issue http://crbug.com/23768 in Chromium.
+// Heap can contain scripts with already disposed external sources.
+// We need to verify that LogCompiledFunctions doesn't crash on them.
+namespace {
+
+class SimpleExternalString : public v8::String::ExternalStringResource {
+ public:
+  explicit SimpleExternalString(const char* source)
+      : utf_source_(strlen(source)) {
+    for (int i = 0; i < utf_source_.length(); ++i)
+      utf_source_[i] = source[i];
+  }
+  virtual ~SimpleExternalString() {}
+  virtual size_t length() const { return utf_source_.length(); }
+  virtual const uint16_t* data() const { return utf_source_.start(); }
+ private:
+  i::ScopedVector<uint16_t> utf_source_;
+};
+
+}  // namespace
+
+TEST(Issue23768) {
+  v8::HandleScope scope;
+  v8::Handle<v8::Context> env = v8::Context::New();
+  env->Enter();
+
+  SimpleExternalString source_ext_str("(function ext() {})();");
+  v8::Local<v8::String> source = v8::String::NewExternal(&source_ext_str);
+  // Script needs to have a name in order to trigger InitLineEnds execution.
+  v8::Handle<v8::String> origin = v8::String::New("issue-23768-test");
+  v8::Handle<v8::Script> evil_script = v8::Script::Compile(source, origin);
+  CHECK(!evil_script.IsEmpty());
+  CHECK(!evil_script->Run().IsEmpty());
+  i::Handle<i::ExternalTwoByteString> i_source(
+      i::ExternalTwoByteString::cast(*v8::Utils::OpenHandle(*source)));
+  // This situation can happen if source was an external string disposed
+  // by its owner.
+  i_source->set_resource(NULL);
+
+  // Must not crash.
+  i::Logger::LogCompiledFunctions();
+}
+
+
 static inline bool IsStringEqualTo(const char* r, const char* s) {
   return strncmp(r, s, strlen(r)) == 0;
 }
diff --git a/deps/v8/test/mjsunit/invalid-source-element.js b/deps/v8/test/mjsunit/invalid-source-element.js
new file mode 100644 (file)
index 0000000..fb012e2
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright 2009 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+// A function expression with no parenthesis around it is not a valid
+// expression statement.
+assertThrows("eval('function() {}')");