Author: [email protected]
Date: Mon Feb 23 05:59:59 2009
New Revision: 1339

Modified:
    branches/experimental/toiger/   (props changed)
    branches/experimental/toiger/src/codegen-arm.cc
    branches/experimental/toiger/src/d8.cc
    branches/experimental/toiger/src/log.cc
    branches/experimental/toiger/src/platform-freebsd.cc
    branches/experimental/toiger/src/platform-linux.cc
    branches/experimental/toiger/src/platform-macos.cc
    branches/experimental/toiger/src/platform-win32.cc
    branches/experimental/toiger/src/platform.h
    branches/experimental/toiger/src/regexp-macro-assembler-ia32.cc
    branches/experimental/toiger/src/regexp-macro-assembler-ia32.h
    branches/experimental/toiger/src/regexp-macro-assembler-irregexp-inl.h    
(props changed)
    branches/experimental/toiger/test/cctest/test-api.cc
     
branches/experimental/toiger/test/mjsunit/global-load-from-eval-in-with.js    
(props changed)
    branches/experimental/toiger/test/mjsunit/local-load-from-eval.js    
(props changed)
    branches/experimental/toiger/test/mjsunit/property-load-across-eval.js    
(props changed)
    branches/experimental/toiger/test/mjsunit/toint32.js
    branches/experimental/toiger/tools/tickprocessor.py

Log:
Experimental: periodic merge from the bleeding edge to the
experimental code generator branch.  Merge up to and including
bleeding_e...@1338.

Modified: branches/experimental/toiger/src/codegen-arm.cc
==============================================================================
--- branches/experimental/toiger/src/codegen-arm.cc     (original)
+++ branches/experimental/toiger/src/codegen-arm.cc     Mon Feb 23 05:59:59 2009
@@ -2086,6 +2086,7 @@
        // been dropped.
        __ ldr(r1, frame_->ElementAt(kNextIndex - 1));
        __ str(r1, MemOperand(r3));
+      // The code slot has already been dropped from the handler.
        frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);

        if (!function_return_is_shadowed_ && i == kReturnShadowIndex) {

Modified: branches/experimental/toiger/src/d8.cc
==============================================================================
--- branches/experimental/toiger/src/d8.cc      (original)
+++ branches/experimental/toiger/src/d8.cc      Mon Feb 23 05:59:59 2009
@@ -419,8 +419,8 @@
  }


-static char* ReadToken(const char* data, char token) {
-  char* next = ::strchr(data, token);
+static char* ReadToken(char* data, char token) {
+  char* next = i::OS::StrChr(data, token);
    if (next != NULL) {
      *next = '\0';
      return (next + 1);
@@ -430,12 +430,12 @@
  }


-static char* ReadLine(const char* data) {
+static char* ReadLine(char* data) {
    return ReadToken(data, '\n');
  }


-static char* ReadWord(const char* data) {
+static char* ReadWord(char* data) {
    return ReadToken(data, ' ');
  }


Modified: branches/experimental/toiger/src/log.cc
==============================================================================
--- branches/experimental/toiger/src/log.cc     (original)
+++ branches/experimental/toiger/src/log.cc     Mon Feb 23 05:59:59 2009
@@ -679,6 +679,7 @@
  }


+#ifdef ENABLE_LOGGING_AND_PROFILING
  int Logger::CodeObjectSize(Code* code) {
    // Check that the assumptions about the layout of the code object holds.
    ASSERT_EQ(reinterpret_cast<unsigned int>(code->instruction_start()) -
@@ -686,6 +687,7 @@
              Code::kHeaderSize);
    return code->instruction_size() + Code::kHeaderSize;
  }
+#endif


  void Logger::CodeCreateEvent(const char* tag, Code* code, const char*  
comment) {

Modified: branches/experimental/toiger/src/platform-freebsd.cc
==============================================================================
--- branches/experimental/toiger/src/platform-freebsd.cc        (original)
+++ branches/experimental/toiger/src/platform-freebsd.cc        Mon Feb 23  
05:59:59 2009
@@ -184,6 +184,11 @@
  }


+char* OS::StrChr(char* str, int c) {
+  return strchr(str, c);
+}
+
+
  void OS::StrNCpy(Vector<char> dest, const char* src, size_t n) {
    strncpy(dest.start(), src, n);
  }

Modified: branches/experimental/toiger/src/platform-linux.cc
==============================================================================
--- branches/experimental/toiger/src/platform-linux.cc  (original)
+++ branches/experimental/toiger/src/platform-linux.cc  Mon Feb 23 05:59:59  
2009
@@ -180,6 +180,11 @@
  }


+char* OS::StrChr(char* str, int c) {
+  return strchr(str, c);
+}
+
+
  void OS::StrNCpy(Vector<char> dest, const char* src, size_t n) {
    strncpy(dest.start(), src, n);
  }

Modified: branches/experimental/toiger/src/platform-macos.cc
==============================================================================
--- branches/experimental/toiger/src/platform-macos.cc  (original)
+++ branches/experimental/toiger/src/platform-macos.cc  Mon Feb 23 05:59:59  
2009
@@ -185,6 +185,11 @@
  }


+char* OS::StrChr(char* str, int c) {
+  return strchr(str, c);
+}
+
+
  void OS::StrNCpy(Vector<char> dest, const char* src, size_t n) {
    strncpy(dest.start(), src, n);
  }

Modified: branches/experimental/toiger/src/platform-win32.cc
==============================================================================
--- branches/experimental/toiger/src/platform-win32.cc  (original)
+++ branches/experimental/toiger/src/platform-win32.cc  Mon Feb 23 05:59:59  
2009
@@ -732,6 +732,11 @@
  }


+char* OS::StrChr(char* str, int c) {
+  return const_cast<char*>(strchr(str, c));
+}
+
+
  void OS::StrNCpy(Vector<char> dest, const char* src, size_t n) {
    int result = strncpy_s(dest.start(), dest.length(), src, n);
    USE(result);

Modified: branches/experimental/toiger/src/platform.h
==============================================================================
--- branches/experimental/toiger/src/platform.h (original)
+++ branches/experimental/toiger/src/platform.h Mon Feb 23 05:59:59 2009
@@ -219,6 +219,7 @@
                         const char* format,
                         va_list args);

+  static char* StrChr(char* str, int c);
    static void StrNCpy(Vector<char> dest, const char* src, size_t n);
    static char* StrDup(const char* str);
    static char* StrNDup(const char* str, size_t n);

Modified: branches/experimental/toiger/src/regexp-macro-assembler-ia32.cc
==============================================================================
--- branches/experimental/toiger/src/regexp-macro-assembler-ia32.cc      
(original)
+++ branches/experimental/toiger/src/regexp-macro-assembler-ia32.cc     Mon Feb 
 
23 05:59:59 2009
@@ -1046,7 +1046,7 @@
  }


-int RegExpMacroAssemblerIA32::CheckStackGuardState(Address return_address,
+int RegExpMacroAssemblerIA32::CheckStackGuardState(Address* return_address,
                                                     Code* re_code) {
    if (StackGuard::IsStackOverflow()) {
      Top::StackOverflow();
@@ -1059,15 +1059,16 @@
    // Prepare for possible GC.
    Handle<Code> code_handle(re_code);

-  ASSERT(re_code->instruction_start() <= return_address);
-  ASSERT(return_address <=
+  ASSERT(re_code->instruction_start() <= *return_address);
+  ASSERT(*return_address <=
        re_code->instruction_start() + re_code->instruction_size());

    Object* result = Execution::HandleStackGuardInterrupt();

    if (*code_handle != re_code) {  // Return address no longer valid
      int delta = *code_handle - re_code;
-    *reinterpret_cast<int32_t*>(return_address) += delta;
+    // Overwrite the return address on the stack.
+    *return_address += delta;
    }

    if (result->IsException()) {

Modified: branches/experimental/toiger/src/regexp-macro-assembler-ia32.h
==============================================================================
--- branches/experimental/toiger/src/regexp-macro-assembler-ia32.h       
(original)
+++ branches/experimental/toiger/src/regexp-macro-assembler-ia32.h      Mon Feb 
 
23 05:59:59 2009
@@ -166,7 +166,7 @@
    // Called from RegExp if the stack-guard is triggered.
    // If the code object is relocated, the return address is fixed before
    // returning.
-  static int CheckStackGuardState(Address return_address, Code* re_code);
+  static int CheckStackGuardState(Address* return_address, Code* re_code);

    // Called from RegExp if the backtrack stack limit is hit.
    // Tries to expand the stack. Returns the new stack-pointer if

Modified: branches/experimental/toiger/test/cctest/test-api.cc
==============================================================================
--- branches/experimental/toiger/test/cctest/test-api.cc        (original)
+++ branches/experimental/toiger/test/cctest/test-api.cc        Mon Feb 23  
05:59:59 2009
@@ -5658,3 +5658,123 @@
    context0.Dispose();
    context1.Dispose();
  }
+
+
+class RegExpInterruptTest {
+ public:
+  void RunTest() {
+    block_ = i::OS::CreateSemaphore(0);
+    gc_count_ = 0;
+    gc_during_regexp_ = 0;
+    regexp_success_ = false;
+    gc_success_ = false;
+    GCThread gc_thread(this);
+    gc_thread.Start();
+    v8::Locker::StartPreemption(1);
+
+    LongRunningRegExp();
+    {
+      v8::Unlocker unlock;
+      gc_thread.Join();
+    }
+    v8::Locker::StopPreemption();
+    CHECK(regexp_success_);
+    CHECK(gc_success_);
+  }
+ private:
+  // Number of garbage collections required.
+  static const int kRequiredGCs = 5;
+
+  class GCThread : public i::Thread {
+   public:
+    explicit GCThread(RegExpInterruptTest* test)
+        : test_(test) {}
+    virtual void Run() {
+      test_->CollectGarbage();
+    }
+   private:
+     RegExpInterruptTest* test_;
+  };
+
+  void CollectGarbage() {
+    block_->Wait();
+    while (gc_during_regexp_ < kRequiredGCs) {
+      {
+        v8::Locker lock;
+        // TODO(lrn): Perhaps create some garbage before collecting.
+        i::Heap::CollectAllGarbage();
+        gc_count_++;
+      }
+      i::OS::Sleep(1);
+    }
+    gc_success_ = true;
+  }
+
+  void LongRunningRegExp() {
+    block_->Signal();  // Enable garbage collection thread on next  
preemption.
+    int rounds = 0;
+    while (gc_during_regexp_ < kRequiredGCs) {
+      int gc_before = gc_count_;
+      {
+        // match 15-30 "a"'s against 14 and a "b".
+        const char* c_source =
+            "/a?a?a?a?a?a?a?a?a?a?a?a?a?a?aaaaaaaaaaaaaaaa/"
+            ".exec('aaaaaaaaaaaaaaab') === null";
+        Local<String> source = String::New(c_source);
+        Local<Script> script = Script::Compile(source);
+        Local<Value> result = script->Run();
+        if (!result->BooleanValue()) {
+          gc_during_regexp_ = kRequiredGCs;  // Allow gc thread to exit.
+          return;
+        }
+      }
+      {
+        // match 15-30 "a"'s against 15 and a "b".
+        const char* c_source =
+            "/a?a?a?a?a?a?a?a?a?a?a?a?a?a?aaaaaaaaaaaaaaaa/"
+            ".exec('aaaaaaaaaaaaaaaab')[0] === 'aaaaaaaaaaaaaaaa'";
+        Local<String> source = String::New(c_source);
+        Local<Script> script = Script::Compile(source);
+        Local<Value> result = script->Run();
+        if (!result->BooleanValue()) {
+          gc_during_regexp_ = kRequiredGCs;
+          return;
+        }
+      }
+      int gc_after = gc_count_;
+      gc_during_regexp_ += gc_after - gc_before;
+      rounds++;
+      i::OS::Sleep(1);
+    }
+    regexp_success_ = true;
+  }
+
+  i::Semaphore* block_;
+  int gc_count_;
+  int gc_during_regexp_;
+  bool regexp_success_;
+  bool gc_success_;
+};
+
+
+// Test that a regular expression execution can be interrupted and
+// survive a garbage collection.
+TEST(RegExpInterruption) {
+  v8::Locker lock;
+  v8::V8::Initialize();
+  v8::HandleScope scope;
+  Local<Context> local_env;
+  {
+    LocalContext env;
+    local_env = env.local();
+  }
+
+  // Local context should still be live.
+  CHECK(!local_env.IsEmpty());
+  local_env->Enter();
+
+  // Should complete without problems.
+  RegExpInterruptTest().RunTest();
+
+  local_env->Exit();
+}

Modified: branches/experimental/toiger/test/mjsunit/toint32.js
==============================================================================
--- branches/experimental/toiger/test/mjsunit/toint32.js        (original)
+++ branches/experimental/toiger/test/mjsunit/toint32.js        Mon Feb 23  
05:59:59 2009
@@ -42,6 +42,10 @@
  assertEquals(1, toInt32(1));
  assertEquals(1, toInt32(1.1));
  assertEquals(-1, toInt32(-1));
+assertEquals(0, toInt32(0.6), "truncate positive (0.6)");
+assertEquals(1, toInt32(1.6), "truncate positive (1.6)");
+assertEquals(0, toInt32(-0.6), "truncate negative (-0.6)");
+assertEquals(-1, toInt32(-1.6), "truncate negative (-1.6)");

  assertEquals(2147483647, toInt32(2147483647));
  assertEquals(-2147483648, toInt32(2147483648));
@@ -78,3 +82,48 @@
  assertEquals(1294967296, toInt32(-3000000000.25));
  assertEquals(1294967296, toInt32(-3000000000.5));
  assertEquals(1294967296, toInt32(-3000000000.75));
+
+var base = Math.pow(2, 64);
+assertEquals(0, toInt32(base + 0));
+assertEquals(0, toInt32(base + 1117));
+assertEquals(4096, toInt32(base + 2234));
+assertEquals(4096, toInt32(base + 3351));
+assertEquals(4096, toInt32(base + 4468));
+assertEquals(4096, toInt32(base + 5585));
+assertEquals(8192, toInt32(base + 6702));
+assertEquals(8192, toInt32(base + 7819));
+assertEquals(8192, toInt32(base + 8936));
+assertEquals(8192, toInt32(base + 10053));
+assertEquals(12288, toInt32(base + 11170));
+assertEquals(12288, toInt32(base + 12287));
+assertEquals(12288, toInt32(base + 13404));
+assertEquals(16384, toInt32(base + 14521));
+assertEquals(16384, toInt32(base + 15638));
+assertEquals(16384, toInt32(base + 16755));
+assertEquals(16384, toInt32(base + 17872));
+assertEquals(20480, toInt32(base + 18989));
+assertEquals(20480, toInt32(base + 20106));
+assertEquals(20480, toInt32(base + 21223));
+assertEquals(20480, toInt32(base + 22340));
+assertEquals(24576, toInt32(base + 23457));
+assertEquals(24576, toInt32(base + 24574));
+assertEquals(24576, toInt32(base + 25691));
+assertEquals(28672, toInt32(base + 26808));
+assertEquals(28672, toInt32(base + 27925));
+assertEquals(28672, toInt32(base + 29042));
+assertEquals(28672, toInt32(base + 30159));
+assertEquals(32768, toInt32(base + 31276));
+
+// bignum is (2^53 - 1) * 2^31 - highest number with bit 31 set.
+var bignum = Math.pow(2, 84) - Math.pow(2, 31);
+assertEquals(-Math.pow(2,31), toInt32(bignum));
+assertEquals(-Math.pow(2,31), toInt32(-bignum));
+assertEquals(0, toInt32(2 * bignum));
+assertEquals(0, toInt32(-(2 * bignum)));
+assertEquals(0, toInt32(bignum - Math.pow(2,31)));
+assertEquals(0, toInt32(-(bignum - Math.pow(2,31))));
+
+// max_fraction is largest number below 1.
+var max_fraction = (1 - Math.pow(2,-53));
+assertEquals(0, toInt32(max_fraction));
+assertEquals(0, toInt32(-max_fraction));

Modified: branches/experimental/toiger/tools/tickprocessor.py
==============================================================================
--- branches/experimental/toiger/tools/tickprocessor.py (original)
+++ branches/experimental/toiger/tools/tickprocessor.py Mon Feb 23 05:59:59  
2009
@@ -386,9 +386,15 @@
          total_stacks += count
      all_stacks_items = all_stacks.items();
      all_stacks_items.sort(key = itemgetter(1), reverse=True)
+    missing_percentage = (self.total_number_of_ticks - total_stacks) *  
100.0 / self.total_number_of_ticks
+    print('  %(ticks)5d  %(total)5.1f%%  <no call path information>' % {
+      'ticks' : self.total_number_of_ticks - total_stacks,
+      'total' : missing_percentage
+    })
      for stack, count in all_stacks_items:
-      total_percentage = count * 100.0 / total_stacks
-      print('  %(total)5.1f%%  %(call_path)s' % {
+      total_percentage = count * 100.0 / self.total_number_of_ticks
+      print('  %(ticks)5d  %(total)5.1f%%  %(call_path)s' % {
+        'ticks' : count,
          'total' : total_percentage,
          'call_path' : stack[0] + '  <-  ' + stack[1]
        })

--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to