Revision: 16426
Author:   [email protected]
Date:     Thu Aug 29 13:18:43 2013 UTC
Log: Merged r16205, r16220, r16237, r16249, r16262, r16269, r16273 into 3.20 branch.

Mark HStringCompareAndBranch as potentially causing GCs.

Prevent empty handle dereference in Runtime_InternalNumberFormat.

Fix null handle deref in InternalDateFormat

Fix a bug in Div when all uses are truncating

Fix "Hole" leak in TryBuildConsolidatedElementLoad

Never clear debug-stub call ICs. Make a clear distinction between is_debug_stub used everywhere but the debugger, and IsDebugBreak, used by the debugger.

Fix deoptimization bug, where recursive call can frighten and confuse the unwitting, simple, poor caveman that is Runtime_NotifyDeoptimized.

BUG=chromium:274438,chromium:275467,274164
[email protected]

Review URL: https://codereview.chromium.org/23761002
http://code.google.com/p/v8/source/detail?r=16426

Added:
 /branches/3.20/test/mjsunit/compiler/regress-shared-deopt.js
 /branches/3.20/test/mjsunit/regress/consolidated-holey-load.js
 /branches/3.20/test/mjsunit/regress/debug-prepare-step-in.js
 /branches/3.20/test/mjsunit/regress/regress-crbug-274438.js
Modified:
 /branches/3.20/src/arm/lithium-codegen-arm.cc
 /branches/3.20/src/debug.cc
 /branches/3.20/src/deoptimizer.h
 /branches/3.20/src/heap.cc
 /branches/3.20/src/heap.h
 /branches/3.20/src/hydrogen-instructions.h
 /branches/3.20/src/hydrogen.cc
 /branches/3.20/src/ia32/lithium-codegen-ia32.cc
 /branches/3.20/src/ic.cc
 /branches/3.20/src/liveedit.cc
 /branches/3.20/src/objects-inl.h
 /branches/3.20/src/objects.h
 /branches/3.20/src/runtime.cc
 /branches/3.20/src/runtime.h
 /branches/3.20/src/version.cc
 /branches/3.20/src/x64/lithium-codegen-x64.cc
 /branches/3.20/test/mjsunit/shift-for-integer-div.js

=======================================
--- /dev/null
+++ /branches/3.20/test/mjsunit/compiler/regress-shared-deopt.js Thu Aug 29 13:18:43 2013 UTC
@@ -0,0 +1,65 @@
+// Copyright 2013 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.
+
+// Flags: --allow-natives-syntax
+
+var soft = false;
+
+// disable optimization of this global
+soft = true;
+soft = false;
+soft = true;
+soft = false;
+
+function test() {
+  var f4 = makeF(4);
+  var f5 = makeF(5);
+
+  function makeF(i) {
+    return function f(x) {
+      if (x == 0) return i;
+      if (i == 4) if (soft) print("wahoo" + i);
+      return f4(x - 1);
+    }
+  }
+
+  f4(9);
+  f4(11);
+  %OptimizeFunctionOnNextCall(f4);
+  f4(12);
+
+  f5(9);
+  f5(11);
+  %OptimizeFunctionOnNextCall(f5);
+  f5(12);
+
+  soft = true;
+  f4(1);
+  f5(9);
+}
+
+test();
=======================================
--- /dev/null
+++ /branches/3.20/test/mjsunit/regress/consolidated-holey-load.js Thu Aug 29 13:18:43 2013 UTC
@@ -0,0 +1,40 @@
+// Copyright 2013 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.
+
+// Flags: --allow-natives-syntax
+
+function foo(array) {
+  return array[0];
+}
+
+var a = [1, 2, , 4];  // Holey Smi elements.
+var b = ["abcd", 0];  // Fast elements.
+foo(b);  // Observe fast elements first, or the IC will transition without
+foo(a);  // going polymorphic.
+%OptimizeFunctionOnNextCall(foo);
+var c = [, 0];
+assertEquals(undefined, foo(c));  // Elided hole check will leak the hole.
=======================================
--- /dev/null
+++ /branches/3.20/test/mjsunit/regress/debug-prepare-step-in.js Thu Aug 29 13:18:43 2013 UTC
@@ -0,0 +1,54 @@
+// Copyright 2013 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.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax --expose-gc
+// Get the Debug object exposed from the debug context global object.
+Debug = debug.Debug
+
+function breakListener(event, exec_state, event_data, data) {
+  exec_state.prepareStep(Debug.StepAction.StepIn, 1);
+}
+
+Debug.setListener(breakListener);
+
+var o = {x:function() { return 10; }};
+
+function f(o) {
+  var m = "x";
+  o[m]();
+}
+
+Debug.setBreakPoint(f, 2, 0);
+
+f(o);
+
+%NotifyContextDisposed();
+function g() {
+  gc();
+}
+
+g();
=======================================
--- /dev/null
+++ /branches/3.20/test/mjsunit/regress/regress-crbug-274438.js Thu Aug 29 13:18:43 2013 UTC
@@ -0,0 +1,43 @@
+// Copyright 2013 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.
+
+// Flags: --allow-natives-syntax
+
+function f(a, b) {
+  var x = { a:a };
+  switch(b) { case "string": }
+  var y = { b:b };
+  return y;
+}
+
+f("a", "b");
+f("a", "b");
+%OptimizeFunctionOnNextCall(f);
+f("a", "b");
+%SetAllocationTimeout(100, 0);
+var killer = f("bang", "bo" + "om");
+assertEquals("boom", killer.b);
=======================================
--- /branches/3.20/src/arm/lithium-codegen-arm.cc Wed Aug 14 17:13:49 2013 UTC +++ /branches/3.20/src/arm/lithium-codegen-arm.cc Thu Aug 29 13:18:43 2013 UTC
@@ -1398,6 +1398,7 @@
         __ rsb(dividend, dividend, Operand(0), LeaveCC, lt);
         __ mov(dividend, Operand(dividend, ASR, power));
if (divisor > 0) __ rsb(dividend, dividend, Operand(0), LeaveCC, lt); + if (divisor < 0) __ rsb(dividend, dividend, Operand(0), LeaveCC, gt);
         return;  // Don't fall through to "__ rsb" below.
       } else {
         // Deoptimize if remainder is not 0.
=======================================
--- /branches/3.20/src/debug.cc Tue Aug 13 17:09:37 2013 UTC
+++ /branches/3.20/src/debug.cc Thu Aug 29 13:18:43 2013 UTC
@@ -1627,7 +1627,7 @@
 // object.
 bool Debug::IsDebugBreak(Address addr) {
   Code* code = Code::GetCodeFromTargetAddress(addr);
-  return code->is_debug_break();
+  return code->is_debug_stub() && code->extra_ic_state() == DEBUG_BREAK;
 }


=======================================
--- /branches/3.20/src/deoptimizer.h    Tue Aug 13 17:09:37 2013 UTC
+++ /branches/3.20/src/deoptimizer.h    Thu Aug 29 13:18:43 2013 UTC
@@ -166,7 +166,9 @@

   int output_count() const { return output_count_; }

-  Code::Kind compiled_code_kind() const { return compiled_code_->kind(); }
+ Handle<JSFunction> function() const { return Handle<JSFunction>(function_); } + Handle<Code> compiled_code() const { return Handle<Code>(compiled_code_); }
+  BailoutType bailout_type() const { return bailout_type_; }

// Number of created JS frames. Not all created frames are necessarily JS.
   int jsframe_count() const { return jsframe_count_; }
=======================================
--- /branches/3.20/src/heap.cc  Tue Aug 13 17:09:37 2013 UTC
+++ /branches/3.20/src/heap.cc  Thu Aug 29 13:18:43 2013 UTC
@@ -4013,10 +4013,10 @@
     return AllocateByteArray(length);
   }
   int size = ByteArray::SizeFor(length);
+  AllocationSpace space =
+      (size > Page::kMaxNonCodeHeapObjectSize) ? LO_SPACE : OLD_DATA_SPACE;
   Object* result;
-  { MaybeObject* maybe_result = (size <= Page::kMaxNonCodeHeapObjectSize)
-                   ? old_data_space_->AllocateRaw(size)
-                   : lo_space_->AllocateRaw(size, NOT_EXECUTABLE);
+  { MaybeObject* maybe_result = AllocateRaw(size, space, space);
     if (!maybe_result->ToObject(&result)) return maybe_result;
   }

=======================================
--- /branches/3.20/src/heap.h   Tue Aug 13 17:09:37 2013 UTC
+++ /branches/3.20/src/heap.h   Thu Aug 29 13:18:43 2013 UTC
@@ -1490,6 +1490,10 @@
inline bool IsInGCPostProcessing() { return gc_post_processing_depth_ > 0; }

 #ifdef DEBUG
+  void set_allocation_timeout(int timeout) {
+    allocation_timeout_ = timeout;
+  }
+
   bool disallow_allocation_failure() {
     return disallow_allocation_failure_;
   }
=======================================
--- /branches/3.20/src/hydrogen-instructions.h  Wed Aug 14 17:13:49 2013 UTC
+++ /branches/3.20/src/hydrogen-instructions.h  Thu Aug 29 13:18:43 2013 UTC
@@ -4081,6 +4081,7 @@
     SetOperandAt(1, left);
     SetOperandAt(2, right);
     set_representation(Representation::Tagged());
+    SetGVNFlag(kChangesNewSpacePromotion);
   }

   HValue* context() { return OperandAt(0); }
=======================================
--- /branches/3.20/src/hydrogen.cc      Wed Aug 14 17:13:49 2013 UTC
+++ /branches/3.20/src/hydrogen.cc      Thu Aug 29 13:18:43 2013 UTC
@@ -5536,6 +5536,7 @@
   bool has_smi_or_object_maps = false;
   bool has_js_array_access = false;
   bool has_non_js_array_access = false;
+  bool has_seen_holey_elements = false;
   Handle<Map> most_general_consolidated_map;
   for (int i = 0; i < maps->length(); ++i) {
     Handle<Map> map = maps->at(i);
@@ -5558,6 +5559,10 @@
     } else {
       return NULL;
     }
+    // Remember if we've ever seen holey elements.
+    if (IsHoleyElementsKind(map->elements_kind())) {
+      has_seen_holey_elements = true;
+    }
     // Remember the most general elements kind, the code for its load will
     // properly handle all of the more specific cases.
     if ((i == 0) || IsMoreGeneralElementsKindTransition(
@@ -5569,10 +5574,15 @@
   if (!has_double_maps && !has_smi_or_object_maps) return NULL;

   HCheckMaps* check_maps = Add<HCheckMaps>(object, maps);
+  // FAST_ELEMENTS is considered more general than FAST_HOLEY_SMI_ELEMENTS.
+ // If we've seen both, the consolidated load must use FAST_HOLEY_ELEMENTS.
+  ElementsKind consolidated_elements_kind = has_seen_holey_elements
+ ? GetHoleyElementsKind(most_general_consolidated_map->elements_kind())
+      : most_general_consolidated_map->elements_kind();
   HInstruction* instr = BuildUncheckedMonomorphicElementAccess(
       object, key, val, check_maps,
       most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE,
-      most_general_consolidated_map->elements_kind(),
+      consolidated_elements_kind,
       false, NEVER_RETURN_HOLE, STANDARD_STORE);
   return instr;
 }
=======================================
--- /branches/3.20/src/ia32/lithium-codegen-ia32.cc Wed Aug 14 17:13:49 2013 UTC +++ /branches/3.20/src/ia32/lithium-codegen-ia32.cc Thu Aug 29 13:18:43 2013 UTC
@@ -1441,6 +1441,7 @@
         __ cmp(dividend, 0);
         __ j(less, &negative, Label::kNear);
         __ sar(dividend, power);
+        if (divisor < 0) __ neg(dividend);
         __ jmp(&done, Label::kNear);

         __ bind(&negative);
=======================================
--- /branches/3.20/src/ic.cc    Tue Aug 13 17:09:37 2013 UTC
+++ /branches/3.20/src/ic.cc    Thu Aug 29 13:18:43 2013 UTC
@@ -379,7 +379,7 @@
   Code* target = GetTargetAtAddress(address);

// Don't clear debug break inline cache as it will remove the break point.
-  if (target->is_debug_break()) return;
+  if (target->is_debug_stub()) return;

   switch (target->kind()) {
     case Code::LOAD_IC: return LoadIC::Clear(address, target);
=======================================
--- /branches/3.20/src/liveedit.cc      Tue Aug 13 17:09:37 2013 UTC
+++ /branches/3.20/src/liveedit.cc      Thu Aug 29 13:18:43 2013 UTC
@@ -1691,7 +1691,7 @@
   Code* pre_top_frame_code = pre_top_frame->LookupCode();
   bool frame_has_padding;
   if (pre_top_frame_code->is_inline_cache_stub() &&
-      pre_top_frame_code->is_debug_break()) {
+      pre_top_frame_code->is_debug_stub()) {
     // OK, we can drop inline cache calls.
     *mode = Debug::FRAME_DROPPED_IN_IC_CALL;
     frame_has_padding = Debug::FramePaddingLayout::kIsSupported;
=======================================
--- /branches/3.20/src/objects-inl.h    Tue Aug 13 17:09:37 2013 UTC
+++ /branches/3.20/src/objects-inl.h    Thu Aug 29 13:18:43 2013 UTC
@@ -4071,8 +4071,8 @@
 }


-bool Code::is_debug_break() {
-  return ic_state() == DEBUG_STUB && extra_ic_state() == DEBUG_BREAK;
+bool Code::is_debug_stub() {
+  return ic_state() == DEBUG_STUB;
 }


=======================================
--- /branches/3.20/src/objects.h        Tue Aug 13 17:09:37 2013 UTC
+++ /branches/3.20/src/objects.h        Thu Aug 29 13:18:43 2013 UTC
@@ -4909,7 +4909,7 @@

   // Testers for IC stub kinds.
   inline bool is_inline_cache_stub();
-  inline bool is_debug_break();
+  inline bool is_debug_stub();
   inline bool is_load_stub() { return kind() == LOAD_IC; }
   inline bool is_keyed_load_stub() { return kind() == KEYED_LOAD_IC; }
   inline bool is_store_stub() { return kind() == STORE_IC; }
=======================================
--- /branches/3.20/src/runtime.cc       Tue Aug 13 17:09:37 2013 UTC
+++ /branches/3.20/src/runtime.cc       Thu Aug 29 13:18:43 2013 UTC
@@ -8294,26 +8294,24 @@

 class ActivationsFinder : public ThreadVisitor {
  public:
-  explicit ActivationsFinder(JSFunction* function)
-      : function_(function), has_activations_(false) {}
+  Code* code_;
+  bool has_code_activations_;
+
+  explicit ActivationsFinder(Code* code)
+    : code_(code),
+      has_code_activations_(false) { }

   void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
-    if (has_activations_) return;
+    JavaScriptFrameIterator it(isolate, top);
+    VisitFrames(&it);
+  }

- for (JavaScriptFrameIterator it(isolate, top); !it.done(); it.Advance()) {
-      JavaScriptFrame* frame = it.frame();
-      if (frame->is_optimized() && frame->function() == function_) {
-        has_activations_ = true;
-        return;
-      }
+  void VisitFrames(JavaScriptFrameIterator* it) {
+    for (; !it->done(); it->Advance()) {
+      JavaScriptFrame* frame = it->frame();
+      if (code_->contains(frame->pc())) has_code_activations_ = true;
     }
   }
-
-  bool has_activations() { return has_activations_; }
-
- private:
-  JSFunction* function_;
-  bool has_activations_;
 };


@@ -8336,7 +8334,11 @@
   Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
   ASSERT(AllowHeapAllocation::IsAllowed());

-  ASSERT(deoptimizer->compiled_code_kind() == Code::OPTIMIZED_FUNCTION);
+  Handle<JSFunction> function = deoptimizer->function();
+  Handle<Code> optimized_code = deoptimizer->compiled_code();
+
+  ASSERT(optimized_code->kind() == Code::OPTIMIZED_FUNCTION);
+  ASSERT(type == deoptimizer->bailout_type());

   // Make sure to materialize objects before causing any allocation.
   JavaScriptFrameIterator it(isolate);
@@ -8345,10 +8347,6 @@

   JavaScriptFrame* frame = it.frame();
   RUNTIME_ASSERT(frame->function()->IsJSFunction());
-  Handle<JSFunction> function(frame->function(), isolate);
-  Handle<Code> optimized_code(function->code());
-  RUNTIME_ASSERT((type != Deoptimizer::EAGER &&
-                  type != Deoptimizer::SOFT) || function->IsOptimized());

   // Avoid doing too much work when running with --always-opt and keep
   // the optimized code around.
@@ -8356,33 +8354,24 @@
     return isolate->heap()->undefined_value();
   }

-  // Find other optimized activations of the function or functions that
-  // share the same optimized code.
-  bool has_other_activations = false;
-  while (!it.done()) {
-    JavaScriptFrame* frame = it.frame();
-    JSFunction* other_function = frame->function();
- if (frame->is_optimized() && other_function->code() == function->code()) {
-      has_other_activations = true;
-      break;
-    }
-    it.Advance();
-  }
-
-  if (!has_other_activations) {
-    ActivationsFinder activations_finder(*function);
-    isolate->thread_manager()->IterateArchivedThreads(&activations_finder);
-    has_other_activations = activations_finder.has_activations();
-  }
+  // Search for other activations of the same function and code.
+  ActivationsFinder activations_finder(*optimized_code);
+  activations_finder.VisitFrames(&it);
+  isolate->thread_manager()->IterateArchivedThreads(&activations_finder);

-  if (!has_other_activations) {
-    if (FLAG_trace_deopt) {
-      PrintF("[removing optimized code for: ");
-      function->PrintName();
-      PrintF("]\n");
+  if (!activations_finder.has_code_activations_) {
+    if (function->code() == *optimized_code) {
+      if (FLAG_trace_deopt) {
+        PrintF("[removing optimized code for: ");
+        function->PrintName();
+        PrintF("]\n");
+      }
+      function->ReplaceCode(function->shared()->code());
     }
-    function->ReplaceCode(function->shared()->code());
   } else {
+    // TODO(titzer): we should probably do DeoptimizeCodeList(code)
+ // unconditionally if the code is not already marked for deoptimization.
+    // If there is an index by shared function info, all the better.
     Deoptimizer::DeoptimizeFunction(*function);
   }
// Evict optimized code for this function from the cache so that it doesn't
@@ -8633,6 +8622,19 @@
     return Smi::FromInt(-1);
   }
 }
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SetAllocationTimeout) {
+  SealHandleScope shs(isolate);
+  ASSERT(args.length() == 2);
+#ifdef DEBUG
+  CONVERT_SMI_ARG_CHECKED(interval, 0);
+  CONVERT_SMI_ARG_CHECKED(timeout, 1);
+  isolate->heap()->set_allocation_timeout(timeout);
+  FLAG_gc_interval = interval;
+#endif
+  return isolate->heap()->undefined_value();
+}


 RUNTIME_FUNCTION(MaybeObject*, Runtime_CheckIsBootstrapping) {
@@ -13639,7 +13641,7 @@
   CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 1);

   bool has_pending_exception = false;
- double millis = Execution::ToNumber(date, &has_pending_exception)->Number();
+  Handle<Object> value = Execution::ToNumber(date, &has_pending_exception);
   if (has_pending_exception) {
     ASSERT(isolate->has_pending_exception());
     return Failure::Exception();
@@ -13650,7 +13652,7 @@
   if (!date_format) return isolate->ThrowIllegalOperation();

   icu::UnicodeString result;
-  date_format->format(millis, result);
+  date_format->format(value->Number(), result);

   return *isolate->factory()->NewStringFromTwoByte(
       Vector<const uint16_t>(
@@ -13743,7 +13745,7 @@
   CONVERT_ARG_HANDLE_CHECKED(Object, number, 1);

   bool has_pending_exception = false;
- double value = Execution::ToNumber(number, &has_pending_exception)->Number(); + Handle<Object> value = Execution::ToNumber(number, &has_pending_exception);
   if (has_pending_exception) {
     ASSERT(isolate->has_pending_exception());
     return Failure::Exception();
@@ -13754,7 +13756,7 @@
   if (!number_format) return isolate->ThrowIllegalOperation();

   icu::UnicodeString result;
-  number_format->format(value, result);
+  number_format->format(value->Number(), result);

   return *isolate->factory()->NewStringFromTwoByte(
       Vector<const uint16_t>(
@@ -13991,6 +13993,14 @@
   FlattenString(str);
   return isolate->heap()->undefined_value();
 }
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyContextDisposed) {
+  HandleScope scope(isolate);
+  ASSERT(args.length() == 0);
+  isolate->heap()->NotifyContextDisposed();
+  return isolate->heap()->undefined_value();
+}


 RUNTIME_FUNCTION(MaybeObject*, Runtime_MigrateInstance) {
=======================================
--- /branches/3.20/src/runtime.h        Tue Aug 13 17:09:37 2013 UTC
+++ /branches/3.20/src/runtime.h        Thu Aug 29 13:18:43 2013 UTC
@@ -101,6 +101,7 @@
   F(GetOptimizationStatus, -1, 1) \
   F(GetOptimizationCount, 1, 1) \
   F(CompileForOnStackReplacement, 1, 1) \
+  F(SetAllocationTimeout, 2, 1) \
   F(AllocateInNewSpace, 1, 1) \
   F(AllocateInOldPointerSpace, 1, 1) \
   F(AllocateInOldDataSpace, 1, 1) \
@@ -110,6 +111,7 @@
   F(DebugPrepareStepInIfStepping, 1, 1) \
   F(FlattenString, 1, 1) \
   F(MigrateInstance, 1, 1) \
+  F(NotifyContextDisposed, 0, 1) \
   \
   /* Array join support */ \
   F(PushIfAbsent, 2, 1) \
=======================================
--- /branches/3.20/src/version.cc       Wed Aug 21 16:32:23 2013 UTC
+++ /branches/3.20/src/version.cc       Thu Aug 29 13:18:43 2013 UTC
@@ -35,7 +35,7 @@
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     20
 #define BUILD_NUMBER      17
-#define PATCH_LEVEL       2
+#define PATCH_LEVEL       3
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
 #define IS_CANDIDATE_VERSION 0
=======================================
--- /branches/3.20/src/x64/lithium-codegen-x64.cc Wed Aug 14 17:13:49 2013 UTC +++ /branches/3.20/src/x64/lithium-codegen-x64.cc Thu Aug 29 13:18:43 2013 UTC
@@ -1216,6 +1216,7 @@
         __ cmpl(dividend, Immediate(0));
         __ j(less, &negative, Label::kNear);
         __ sarl(dividend, Immediate(power));
+        if (divisor < 0) __ negl(dividend);
         __ jmp(&done, Label::kNear);

         __ bind(&negative);
=======================================
--- /branches/3.20/test/mjsunit/shift-for-integer-div.js Mon Dec 10 19:00:50 2012 UTC +++ /branches/3.20/test/mjsunit/shift-for-integer-div.js Thu Aug 29 13:18:43 2013 UTC
@@ -25,35 +25,63 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+// Flags: --allow-natives-syntax
+
 function divp4(x) {
   return x / 4;
 }

-for (var i = 0; i < 10000; i+=4) {
-  assertEquals(i >> 2, divp4(i));
-}
-
+divp4(8);
+divp4(8);
+%OptimizeFunctionOnNextCall(divp4);
+assertEquals(2, divp4(8));
 assertEquals(0.5, divp4(2));

+
 function divn4(x) {
   return x / (-4);
 }

-for (var i = 0; i < 10000; i+=4) {
-  assertEquals(-(i >> 2), divn4(i));
-}
-
+divn4(8);
+divn4(8);
+%OptimizeFunctionOnNextCall(divn4);
+assertEquals(-2, divn4(8));
+// Check for (0 / -x)
 assertEquals(-0, divn4(0));


+// Check for (kMinInt / -1)
 function divn1(x) {
   return x / (-1);
 }

-for (var i = 0; i < 10000; i++) {
-  assertEquals(-i, divn1(i));
+var two_31 = 1 << 31;
+divn1(2);
+divn1(2);
+%OptimizeFunctionOnNextCall(divn1);
+assertEquals(-2, divn1(2));
+assertEquals(two_31, divn1(-two_31));
+
+
+//Check for truncating to int32 case
+function divp4t(x) {
+  return (x / 4) | 0;
 }

-var min_int = -(0x7FFFFFFF)-1;
-assertEquals(-min_int, divn1(min_int));
+divp4t(8);
+divp4t(8);
+%OptimizeFunctionOnNextCall(divp4t);
+assertEquals(-1, divp4t(-5));
+assertEquals(1, divp4t(5));
+assertOptimized(divp4t);
+
+function divn4t(x) {
+  return (x / -4) | 0;
+}

+divn4t(8);
+divn4t(8);
+%OptimizeFunctionOnNextCall(divn4t);
+assertEquals(1, divn4t(-5));
+assertEquals(-1, divn4t(5));
+assertOptimized(divn4t);

--
--
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/groups/opt_out.

Reply via email to