Revision: 21760
Author:   [email protected]
Date:     Wed Jun 11 08:48:10 2014 UTC
Log:      Version 3.27.25 (based on bleeding_edge revision r21759)

Performance and stability improvements on all platforms.
http://code.google.com/p/v8/source/detail?r=21760

Modified:
 /trunk/BUILD.gn
 /trunk/ChangeLog
 /trunk/src/arm/code-stubs-arm.cc
 /trunk/src/arm/code-stubs-arm.h
 /trunk/src/ia32/code-stubs-ia32.cc
 /trunk/src/ia32/code-stubs-ia32.h
 /trunk/src/isolate.cc
 /trunk/src/isolate.h
 /trunk/src/version.cc
 /trunk/src/x64/code-stubs-x64.cc
 /trunk/src/x64/code-stubs-x64.h
 /trunk/test/cctest/test-api.cc

=======================================
--- /trunk/BUILD.gn     Wed Jun 11 00:05:05 2014 UTC
+++ /trunk/BUILD.gn     Wed Jun 11 08:48:10 2014 UTC
@@ -447,6 +447,9 @@
     "src/fast-dtoa.cc",
     "src/fast-dtoa.h",
     "src/feedback-slots.h",
+    "src/field-index.cc",
+    "src/field-index.h",
+    "src/field-index-inl.h",
     "src/fixed-dtoa.cc",
     "src/fixed-dtoa.h",
     "src/flag-definitions.h",
=======================================
--- /trunk/ChangeLog    Wed Jun 11 00:05:05 2014 UTC
+++ /trunk/ChangeLog    Wed Jun 11 08:48:10 2014 UTC
@@ -1,3 +1,8 @@
+2014-06-11: Version 3.27.25
+
+        Performance and stability improvements on all platforms.
+
+
 2014-06-11: Version 3.27.24

Fix invalid attributes when generalizing because of incompatible map
=======================================
--- /trunk/src/arm/code-stubs-arm.cc    Wed Jun  4 00:06:13 2014 UTC
+++ /trunk/src/arm/code-stubs-arm.cc    Wed Jun 11 08:48:10 2014 UTC
@@ -3322,142 +3322,37 @@
 };


-void StringHelper::GenerateCopyCharactersLong(MacroAssembler* masm,
-                                              Register dest,
-                                              Register src,
-                                              Register count,
-                                              Register scratch1,
-                                              Register scratch2,
-                                              Register scratch3,
-                                              Register scratch4,
-                                              int flags) {
-  bool ascii = (flags & COPY_ASCII) != 0;
-  bool dest_always_aligned = (flags & DEST_ALWAYS_ALIGNED) != 0;
-
-  if (dest_always_aligned && FLAG_debug_code) {
-    // Check that destination is actually word aligned if the flag says
-    // that it is.
+void StringHelper::GenerateCopyCharacters(MacroAssembler* masm,
+                                          Register dest,
+                                          Register src,
+                                          Register count,
+                                          Register scratch,
+                                          String::Encoding encoding) {
+  if (FLAG_debug_code) {
+    // Check that destination is word aligned.
     __ tst(dest, Operand(kPointerAlignmentMask));
     __ Check(eq, kDestinationOfCopyNotAligned);
   }

-  const int kReadAlignment = 4;
-  const int kReadAlignmentMask = kReadAlignment - 1;
- // Ensure that reading an entire aligned word containing the last character - // of a string will not read outside the allocated area (because we pad up
-  // to kObjectAlignment).
-  STATIC_ASSERT(kObjectAlignment >= kReadAlignment);
   // Assumes word reads and writes are little endian.
   // Nothing to do for zero characters.
   Label done;
-  if (!ascii) {
+  if (encoding == String::TWO_BYTE_ENCODING) {
     __ add(count, count, Operand(count), SetCC);
-  } else {
-    __ cmp(count, Operand::Zero());
   }
-  __ b(eq, &done);

-  // Assume that you cannot read (or write) unaligned.
-  Label byte_loop;
- // Must copy at least eight bytes, otherwise just do it one byte at a time.
-  __ cmp(count, Operand(8));
-  __ add(count, dest, Operand(count));
-  Register limit = count;  // Read until src equals this.
-  __ b(lt, &byte_loop);
+  Register limit = count;  // Read until dest equals this.
+  __ add(limit, dest, Operand(count));

-  if (!dest_always_aligned) {
-    // Align dest by byte copying. Copies between zero and three bytes.
-    __ and_(scratch4, dest, Operand(kReadAlignmentMask), SetCC);
-    Label dest_aligned;
-    __ b(eq, &dest_aligned);
-    __ cmp(scratch4, Operand(2));
-    __ ldrb(scratch1, MemOperand(src, 1, PostIndex));
-    __ ldrb(scratch2, MemOperand(src, 1, PostIndex), le);
-    __ ldrb(scratch3, MemOperand(src, 1, PostIndex), lt);
-    __ strb(scratch1, MemOperand(dest, 1, PostIndex));
-    __ strb(scratch2, MemOperand(dest, 1, PostIndex), le);
-    __ strb(scratch3, MemOperand(dest, 1, PostIndex), lt);
-    __ bind(&dest_aligned);
-  }
-
-  Label simple_loop;
-
-  __ sub(scratch4, dest, Operand(src));
-  __ and_(scratch4, scratch4, Operand(0x03), SetCC);
-  __ b(eq, &simple_loop);
-  // Shift register is number of bits in a source word that
-  // must be combined with bits in the next source word in order
-  // to create a destination word.
-
-  // Complex loop for src/dst that are not aligned the same way.
-  {
-    Label loop;
-    __ mov(scratch4, Operand(scratch4, LSL, 3));
-    Register left_shift = scratch4;
-    __ and_(src, src, Operand(~3));  // Round down to load previous word.
-    __ ldr(scratch1, MemOperand(src, 4, PostIndex));
-    // Store the "shift" most significant bits of scratch in the least
-    // signficant bits (i.e., shift down by (32-shift)).
-    __ rsb(scratch2, left_shift, Operand(32));
-    Register right_shift = scratch2;
-    __ mov(scratch1, Operand(scratch1, LSR, right_shift));
-
-    __ bind(&loop);
-    __ ldr(scratch3, MemOperand(src, 4, PostIndex));
-    __ orr(scratch1, scratch1, Operand(scratch3, LSL, left_shift));
-    __ str(scratch1, MemOperand(dest, 4, PostIndex));
-    __ mov(scratch1, Operand(scratch3, LSR, right_shift));
-    // Loop if four or more bytes left to copy.
-    __ sub(scratch3, limit, Operand(dest));
-    __ sub(scratch3, scratch3, Operand(4), SetCC);
-    __ b(ge, &loop);
-  }
-  // There is now between zero and three bytes left to copy (negative that
- // number is in scratch3), and between one and three bytes already read into
-  // scratch1 (eight times that number in scratch4). We may have read past
- // the end of the string, but because objects are aligned, we have not read
-  // past the end of the object.
- // Find the minimum of remaining characters to move and preloaded characters
-  // and write those as bytes.
-  __ add(scratch3, scratch3, Operand(4), SetCC);
-  __ b(eq, &done);
-  __ cmp(scratch4, Operand(scratch3, LSL, 3), ne);
-  // Move minimum of bytes read and bytes left to copy to scratch4.
-  __ mov(scratch3, Operand(scratch4, LSR, 3), LeaveCC, lt);
-  // Between one and three (value in scratch3) characters already read into
-  // scratch ready to write.
-  __ cmp(scratch3, Operand(2));
-  __ strb(scratch1, MemOperand(dest, 1, PostIndex));
-  __ mov(scratch1, Operand(scratch1, LSR, 8), LeaveCC, ge);
-  __ strb(scratch1, MemOperand(dest, 1, PostIndex), ge);
-  __ mov(scratch1, Operand(scratch1, LSR, 8), LeaveCC, gt);
-  __ strb(scratch1, MemOperand(dest, 1, PostIndex), gt);
-  // Copy any remaining bytes.
-  __ b(&byte_loop);
-
-  // Simple loop.
-  // Copy words from src to dst, until less than four bytes left.
-  // Both src and dest are word aligned.
-  __ bind(&simple_loop);
-  {
-    Label loop;
-    __ bind(&loop);
-    __ ldr(scratch1, MemOperand(src, 4, PostIndex));
-    __ sub(scratch3, limit, Operand(dest));
-    __ str(scratch1, MemOperand(dest, 4, PostIndex));
- // Compare to 8, not 4, because we do the substraction before increasing
-    // dest.
-    __ cmp(scratch3, Operand(8));
-    __ b(ge, &loop);
-  }
-
-  // Copy bytes from src to dst until dst hits limit.
-  __ bind(&byte_loop);
+  Label loop_entry, loop;
+  // Copy bytes from src to dest until dest hits limit.
+  __ b(&loop_entry);
+  __ bind(&loop);
+  __ ldrb(scratch, MemOperand(src, 1, PostIndex), lt);
+  __ strb(scratch, MemOperand(dest, 1, PostIndex));
+  __ bind(&loop_entry);
   __ cmp(dest, Operand(limit));
-  __ ldrb(scratch1, MemOperand(src, 1, PostIndex), lt);
-  __ b(ge, &done);
-  __ strb(scratch1, MemOperand(dest, 1, PostIndex));
-  __ b(&byte_loop);
+  __ b(lt, &loop);

   __ bind(&done);
 }
@@ -3683,8 +3578,8 @@
   // r2: result string length
   // r5: first character of substring to copy
STATIC_ASSERT((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0); - StringHelper::GenerateCopyCharactersLong(masm, r1, r5, r2, r3, r4, r6, r9, - COPY_ASCII | DEST_ALWAYS_ALIGNED);
+  StringHelper::GenerateCopyCharacters(
+      masm, r1, r5, r2, r3, String::ONE_BYTE_ENCODING);
   __ jmp(&return_r0);

   // Allocate and copy the resulting two-byte string.
@@ -3702,8 +3597,8 @@
   // r2: result length.
   // r5: first character of substring to copy.
STATIC_ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0);
-  StringHelper::GenerateCopyCharactersLong(
-      masm, r1, r5, r2, r3, r4, r6, r9, DEST_ALWAYS_ALIGNED);
+  StringHelper::GenerateCopyCharacters(
+      masm, r1, r5, r2, r3, String::TWO_BYTE_ENCODING);

   __ bind(&return_r0);
   Counters* counters = isolate()->counters();
=======================================
--- /trunk/src/arm/code-stubs-arm.h     Wed Jun  4 00:06:13 2014 UTC
+++ /trunk/src/arm/code-stubs-arm.h     Wed Jun 11 08:48:10 2014 UTC
@@ -38,15 +38,12 @@
   // is allowed to spend extra time setting up conditions to make copying
   // faster. Copying of overlapping regions is not supported.
   // Dest register ends at the position after the last character written.
-  static void GenerateCopyCharactersLong(MacroAssembler* masm,
-                                         Register dest,
-                                         Register src,
-                                         Register count,
-                                         Register scratch1,
-                                         Register scratch2,
-                                         Register scratch3,
-                                         Register scratch4,
-                                         int flags);
+  static void GenerateCopyCharacters(MacroAssembler* masm,
+                                     Register dest,
+                                     Register src,
+                                     Register count,
+                                     Register scratch,
+                                     String::Encoding encoding);


   // Generate string hash.
=======================================
--- /trunk/src/ia32/code-stubs-ia32.cc  Wed Jun  4 00:06:13 2014 UTC
+++ /trunk/src/ia32/code-stubs-ia32.cc  Wed Jun 11 08:48:10 2014 UTC
@@ -3180,18 +3180,12 @@
 }


-void StringHelper::GenerateCopyCharactersREP(MacroAssembler* masm,
-                                             Register dest,
-                                             Register src,
-                                             Register count,
-                                             Register scratch,
-                                             bool ascii) {
-  // Copy characters using rep movs of doublewords.
-  // The destination is aligned on a 4 byte boundary because we are
-  // copying to the beginning of a newly allocated string.
-  ASSERT(dest.is(edi));  // rep movs destination
-  ASSERT(src.is(esi));  // rep movs source
-  ASSERT(count.is(ecx));  // rep movs count
+void StringHelper::GenerateCopyCharacters(MacroAssembler* masm,
+                                          Register dest,
+                                          Register src,
+                                          Register count,
+                                          Register scratch,
+                                          String::Encoding encoding) {
   ASSERT(!scratch.is(dest));
   ASSERT(!scratch.is(src));
   ASSERT(!scratch.is(count));
@@ -3202,38 +3196,17 @@
   __ j(zero, &done);

   // Make count the number of bytes to copy.
-  if (!ascii) {
+  if (encoding == String::TWO_BYTE_ENCODING) {
     __ shl(count, 1);
   }

-  // Don't enter the rep movs if there are less than 4 bytes to copy.
-  Label last_bytes;
-  __ test(count, Immediate(~3));
-  __ j(zero, &last_bytes, Label::kNear);
-
-  // Copy from edi to esi using rep movs instruction.
-  __ mov(scratch, count);
-  __ sar(count, 2);  // Number of doublewords to copy.
-  __ cld();
-  __ rep_movs();
-
-  // Find number of bytes left.
-  __ mov(count, scratch);
-  __ and_(count, 3);
-
-  // Check if there are more bytes to copy.
-  __ bind(&last_bytes);
-  __ test(count, count);
-  __ j(zero, &done);
-
-  // Copy remaining characters.
   Label loop;
   __ bind(&loop);
   __ mov_b(scratch, Operand(src, 0));
   __ mov_b(Operand(dest, 0), scratch);
-  __ add(src, Immediate(1));
-  __ add(dest, Immediate(1));
-  __ sub(count, Immediate(1));
+  __ inc(src);
+  __ inc(dest);
+  __ dec(count);
   __ j(not_zero, &loop);

   __ bind(&done);
@@ -3462,23 +3435,21 @@

   // eax: result string
   // ecx: result string length
-  __ mov(edx, esi);  // esi used by following code.
   // Locate first character of result.
   __ mov(edi, eax);
   __ add(edi, Immediate(SeqOneByteString::kHeaderSize - kHeapObjectTag));
   // Load string argument and locate character of sub string start.
-  __ pop(esi);
+  __ pop(edx);
   __ pop(ebx);
   __ SmiUntag(ebx);
- __ lea(esi, FieldOperand(esi, ebx, times_1, SeqOneByteString::kHeaderSize)); + __ lea(edx, FieldOperand(edx, ebx, times_1, SeqOneByteString::kHeaderSize));

   // eax: result string
   // ecx: result length
-  // edx: original value of esi
   // edi: first character of result
-  // esi: character of sub string start
-  StringHelper::GenerateCopyCharactersREP(masm, edi, esi, ecx, ebx, true);
-  __ mov(esi, edx);  // Restore esi.
+  // edx: character of sub string start
+  StringHelper::GenerateCopyCharacters(
+      masm, edi, edx, ecx, ebx, String::ONE_BYTE_ENCODING);
   __ IncrementCounter(counters->sub_string_native(), 1);
   __ ret(3 * kPointerSize);

@@ -3488,27 +3459,25 @@

   // eax: result string
   // ecx: result string length
-  __ mov(edx, esi);  // esi used by following code.
   // Locate first character of result.
   __ mov(edi, eax);
   __ add(edi,
          Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
   // Load string argument and locate character of sub string start.
-  __ pop(esi);
+  __ pop(edx);
   __ pop(ebx);
// As from is a smi it is 2 times the value which matches the size of a two
   // byte character.
   STATIC_ASSERT(kSmiTag == 0);
   STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1);
- __ lea(esi, FieldOperand(esi, ebx, times_1, SeqTwoByteString::kHeaderSize)); + __ lea(edx, FieldOperand(edx, ebx, times_1, SeqTwoByteString::kHeaderSize));

   // eax: result string
   // ecx: result length
-  // edx: original value of esi
   // edi: first character of result
-  // esi: character of sub string start
-  StringHelper::GenerateCopyCharactersREP(masm, edi, esi, ecx, ebx, false);
-  __ mov(esi, edx);  // Restore esi.
+  // edx: character of sub string start
+  StringHelper::GenerateCopyCharacters(
+      masm, edi, edx, ecx, ebx, String::TWO_BYTE_ENCODING);
   __ IncrementCounter(counters->sub_string_native(), 1);
   __ ret(3 * kPointerSize);

=======================================
--- /trunk/src/ia32/code-stubs-ia32.h   Wed Jun  4 00:06:13 2014 UTC
+++ /trunk/src/ia32/code-stubs-ia32.h   Wed Jun 11 08:48:10 2014 UTC
@@ -40,12 +40,12 @@
   // Generate code for copying characters using the rep movs instruction.
// Copies ecx characters from esi to edi. Copying of overlapping regions is
   // not supported.
-  static void GenerateCopyCharactersREP(MacroAssembler* masm,
-                                        Register dest,     // Must be edi.
-                                        Register src,      // Must be esi.
-                                        Register count,    // Must be ecx.
- Register scratch, // Neither of above.
-                                        bool ascii);
+  static void GenerateCopyCharacters(MacroAssembler* masm,
+                                     Register dest,
+                                     Register src,
+                                     Register count,
+                                     Register scratch,
+                                     String::Encoding encoding);

   // Generate string hash.
   static void GenerateHashInit(MacroAssembler* masm,
=======================================
--- /trunk/src/isolate.cc       Fri Jun  6 00:04:56 2014 UTC
+++ /trunk/src/isolate.cc       Wed Jun 11 08:48:10 2014 UTC
@@ -1166,20 +1166,15 @@
 }


-bool Isolate::IsExternallyCaught() {
+bool Isolate::HasExternalTryCatch() {
   ASSERT(has_pending_exception());

-  if ((thread_local_top()->catcher_ == NULL) ||
-      (try_catch_handler() != thread_local_top()->catcher_)) {
-    // When throwing the exception, we found no v8::TryCatch
-    // which should care about this exception.
-    return false;
-  }
+  return (thread_local_top()->catcher_ != NULL) &&
+      (try_catch_handler() == thread_local_top()->catcher_);
+}

-  if (!is_catchable_by_javascript(pending_exception())) {
-    return true;
-  }

+bool Isolate::IsFinallyOnTop() {
// Get the address of the external handler so we can compare the address to
   // determine which one is closer to the top of the stack.
   Address external_handler_address =
@@ -1199,18 +1194,18 @@
       StackHandler::FromAddress(Isolate::handler(thread_local_top()));
while (handler != NULL && handler->address() < external_handler_address) {
     ASSERT(!handler->is_catch());
-    if (handler->is_finally()) return false;
+    if (handler->is_finally()) return true;

     handler = handler->next();
   }

-  return true;
+  return false;
 }


 void Isolate::ReportPendingMessages() {
   ASSERT(has_pending_exception());
-  PropagatePendingExceptionToExternalTryCatch();
+  bool can_clear_message = PropagatePendingExceptionToExternalTryCatch();

   HandleScope scope(this);
   if (thread_local_top_.pending_exception_ ==
@@ -1237,7 +1232,7 @@
       }
     }
   }
-  clear_pending_message();
+  if (can_clear_message) clear_pending_message();
 }


@@ -1742,14 +1737,22 @@
 }


-void Isolate::PropagatePendingExceptionToExternalTryCatch() {
+bool Isolate::PropagatePendingExceptionToExternalTryCatch() {
   ASSERT(has_pending_exception());

-  bool external_caught = IsExternallyCaught();
-  thread_local_top_.external_caught_exception_ = external_caught;
+  bool has_external_try_catch = HasExternalTryCatch();
+  if (!has_external_try_catch) {
+    thread_local_top_.external_caught_exception_ = false;
+    return true;
+  }

-  if (!external_caught) return;
+  bool catchable_by_js = is_catchable_by_javascript(pending_exception());
+  if (catchable_by_js && IsFinallyOnTop()) {
+    thread_local_top_.external_caught_exception_ = false;
+    return false;
+  }

+  thread_local_top_.external_caught_exception_ = true;
   if (thread_local_top_.pending_exception_ ==
              heap()->termination_exception()) {
     try_catch_handler()->can_continue_ = false;
@@ -1765,13 +1768,14 @@
     handler->has_terminated_ = false;
     handler->exception_ = pending_exception();
// Propagate to the external try-catch only if we got an actual message.
-    if (thread_local_top_.pending_message_obj_->IsTheHole()) return;
+    if (thread_local_top_.pending_message_obj_->IsTheHole()) return true;

     handler->message_obj_ = thread_local_top_.pending_message_obj_;
     handler->message_script_ = thread_local_top_.pending_message_script_;
handler->message_start_pos_ = thread_local_top_.pending_message_start_pos_;
     handler->message_end_pos_ = thread_local_top_.pending_message_end_pos_;
   }
+  return true;
 }


=======================================
--- /trunk/src/isolate.h        Fri Jun  6 00:04:56 2014 UTC
+++ /trunk/src/isolate.h        Wed Jun 11 08:48:10 2014 UTC
@@ -604,7 +604,8 @@
     thread_local_top_.scheduled_exception_ = heap_.the_hole_value();
   }

-  bool IsExternallyCaught();
+  bool HasExternalTryCatch();
+  bool IsFinallyOnTop();

   bool is_catchable_by_javascript(Object* exception) {
     return exception != heap()->termination_exception();
@@ -1179,7 +1180,10 @@

   void FillCache();

-  void PropagatePendingExceptionToExternalTryCatch();
+  // Propagate pending exception message to the v8::TryCatch.
+ // If there is no external try-catch or message was successfully propagated,
+  // then return true.
+  bool PropagatePendingExceptionToExternalTryCatch();

// Traverse prototype chain to find out whether the object is derived from
   // the Error object.
=======================================
--- /trunk/src/version.cc       Wed Jun 11 00:05:05 2014 UTC
+++ /trunk/src/version.cc       Wed Jun 11 08:48:10 2014 UTC
@@ -34,7 +34,7 @@
 // system so their names cannot be changed without changing the scripts.
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     27
-#define BUILD_NUMBER      24
+#define BUILD_NUMBER      25
 #define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
=======================================
--- /trunk/src/x64/code-stubs-x64.cc    Wed Jun  4 00:06:13 2014 UTC
+++ /trunk/src/x64/code-stubs-x64.cc    Wed Jun 11 08:48:10 2014 UTC
@@ -3134,49 +3134,21 @@
 }


-void StringHelper::GenerateCopyCharactersREP(MacroAssembler* masm,
-                                             Register dest,
-                                             Register src,
-                                             Register count,
-                                             bool ascii) {
- // Copy characters using rep movs of doublewords. Align destination on 4 byte - // boundary before starting rep movs. Copy remaining characters after running
-  // rep movs.
-  // Count is positive int32, dest and src are character pointers.
-  ASSERT(dest.is(rdi));  // rep movs destination
-  ASSERT(src.is(rsi));  // rep movs source
-  ASSERT(count.is(rcx));  // rep movs count
-
+void StringHelper::GenerateCopyCharacters(MacroAssembler* masm,
+                                          Register dest,
+                                          Register src,
+                                          Register count,
+                                          String::Encoding encoding) {
   // Nothing to do for zero characters.
   Label done;
   __ testl(count, count);
   __ j(zero, &done, Label::kNear);

   // Make count the number of bytes to copy.
-  if (!ascii) {
+  if (encoding == String::TWO_BYTE_ENCODING) {
     STATIC_ASSERT(2 == sizeof(uc16));
     __ addl(count, count);
   }
-
-  // Don't enter the rep movs if there are less than 4 bytes to copy.
-  Label last_bytes;
-  __ testl(count, Immediate(~(kPointerSize - 1)));
-  __ j(zero, &last_bytes, Label::kNear);
-
-  // Copy from edi to esi using rep movs instruction.
-  __ movl(kScratchRegister, count);
-  // Number of doublewords to copy.
-  __ shrl(count, Immediate(kPointerSizeLog2));
-  __ repmovsp();
-
-  // Find number of bytes left.
-  __ movl(count, kScratchRegister);
-  __ andp(count, Immediate(kPointerSize - 1));
-
-  // Check if there are more bytes to copy.
-  __ bind(&last_bytes);
-  __ testl(count, count);
-  __ j(zero, &done, Label::kNear);

   // Copy remaining characters.
   Label loop;
@@ -3415,10 +3387,9 @@

   // rax: result string
   // rcx: result string length
-  __ movp(r14, rsi);  // esi used by following code.
   {  // Locate character of sub string start.
     SmiIndex smi_as_index = masm->SmiToIndex(rdx, rdx, times_1);
-    __ leap(rsi, Operand(rdi, smi_as_index.reg, smi_as_index.scale,
+    __ leap(r14, Operand(rdi, smi_as_index.reg, smi_as_index.scale,
                         SeqOneByteString::kHeaderSize - kHeapObjectTag));
   }
   // Locate first character of result.
@@ -3426,11 +3397,10 @@

   // rax: result string
   // rcx: result length
-  // rdi: first character of result
+  // r14: first character of result
   // rsi: character of sub string start
-  // r14: original value of rsi
-  StringHelper::GenerateCopyCharactersREP(masm, rdi, rsi, rcx, true);
-  __ movp(rsi, r14);  // Restore rsi.
+  StringHelper::GenerateCopyCharacters(
+      masm, rdi, r14, rcx, String::ONE_BYTE_ENCODING);
   __ IncrementCounter(counters->sub_string_native(), 1);
   __ ret(SUB_STRING_ARGUMENT_COUNT * kPointerSize);

@@ -3440,10 +3410,9 @@

   // rax: result string
   // rcx: result string length
-  __ movp(r14, rsi);  // esi used by following code.
   {  // Locate character of sub string start.
     SmiIndex smi_as_index = masm->SmiToIndex(rdx, rdx, times_2);
-    __ leap(rsi, Operand(rdi, smi_as_index.reg, smi_as_index.scale,
+    __ leap(r14, Operand(rdi, smi_as_index.reg, smi_as_index.scale,
                         SeqOneByteString::kHeaderSize - kHeapObjectTag));
   }
   // Locate first character of result.
@@ -3452,10 +3421,9 @@
   // rax: result string
   // rcx: result length
   // rdi: first character of result
-  // rsi: character of sub string start
-  // r14: original value of rsi
-  StringHelper::GenerateCopyCharactersREP(masm, rdi, rsi, rcx, false);
-  __ movp(rsi, r14);  // Restore esi.
+  // r14: character of sub string start
+  StringHelper::GenerateCopyCharacters(
+      masm, rdi, r14, rcx, String::TWO_BYTE_ENCODING);
   __ IncrementCounter(counters->sub_string_native(), 1);
   __ ret(SUB_STRING_ARGUMENT_COUNT * kPointerSize);

=======================================
--- /trunk/src/x64/code-stubs-x64.h     Wed Jun  4 00:06:13 2014 UTC
+++ /trunk/src/x64/code-stubs-x64.h     Wed Jun 11 08:48:10 2014 UTC
@@ -36,11 +36,11 @@
   // Generate code for copying characters using the rep movs instruction.
// Copies rcx characters from rsi to rdi. Copying of overlapping regions is
   // not supported.
-  static void GenerateCopyCharactersREP(MacroAssembler* masm,
-                                        Register dest,     // Must be rdi.
-                                        Register src,      // Must be rsi.
-                                        Register count,    // Must be rcx.
-                                        bool ascii);
+  static void GenerateCopyCharacters(MacroAssembler* masm,
+                                     Register dest,
+                                     Register src,
+                                     Register count,
+                                     String::Encoding encoding);


   // Generate string hash.
=======================================
--- /trunk/test/cctest/test-api.cc      Fri Jun  6 00:04:56 2014 UTC
+++ /trunk/test/cctest/test-api.cc      Wed Jun 11 08:48:10 2014 UTC
@@ -8360,6 +8360,41 @@
       "})()");
   CHECK(try_catch.HasCaught());
 }
+
+
+void CEvaluate(const v8::FunctionCallbackInfo<v8::Value>& args) {
+  v8::HandleScope scope(args.GetIsolate());
+  CompileRun(args[0]->ToString());
+}
+
+
+TEST(TryCatchFinallyStoresMessageUsingTryCatchHandler) {
+  v8::Isolate* isolate = CcTest::isolate();
+  v8::HandleScope scope(isolate);
+  Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
+  templ->Set(v8_str("CEvaluate"),
+             v8::FunctionTemplate::New(isolate, CEvaluate));
+  LocalContext context(0, templ);
+  v8::TryCatch try_catch;
+  CompileRun("try {"
+             "  CEvaluate('throw 1;');"
+             "} finally {"
+             "}");
+  CHECK(try_catch.HasCaught());
+  CHECK(!try_catch.Message().IsEmpty());
+  String::Utf8Value exception_value(try_catch.Exception());
+  CHECK_EQ(*exception_value, "1");
+  try_catch.Reset();
+  CompileRun("try {"
+             "  CEvaluate('throw 1;');"
+             "} finally {"
+             "  throw 2;"
+             "}");
+  CHECK(try_catch.HasCaught());
+  CHECK(!try_catch.Message().IsEmpty());
+  String::Utf8Value finally_exception_value(try_catch.Exception());
+  CHECK_EQ(*finally_exception_value, "2");
+}


 // For use within the TestSecurityHandler() test.

--
--
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