Revision: 3321
Author: [email protected]
Date: Tue Nov 17 13:43:00 2009
Log: Merge r3285, r3313, and r3318 to branches/1.3. This includes fixes to  
avoid bogus FatalProcessOutOfMemory issues (3285), 13.4% compiled code size  
reduction (3313), and a critical fix to avoid potentially orphaning global  
handles (3318).
Review URL: http://codereview.chromium.org/399044
http://code.google.com/p/v8/source/detail?r=3321

Modified:
  /branches/1.3/src/global-handles.cc
  /branches/1.3/src/heap.cc
  /branches/1.3/src/ia32/codegen-ia32.cc
  /branches/1.3/src/ia32/codegen-ia32.h
  /branches/1.3/src/ia32/register-allocator-ia32.cc
  /branches/1.3/src/ia32/virtual-frame-ia32.cc
  /branches/1.3/src/runtime.cc
  /branches/1.3/src/version.cc
  /branches/1.3/test/cctest/test-api.cc

=======================================
--- /branches/1.3/src/global-handles.cc Wed Oct 28 07:53:37 2009
+++ /branches/1.3/src/global-handles.cc Tue Nov 17 13:43:00 2009
@@ -165,6 +165,9 @@
        // It's fine though to reuse nodes that were destroyed in weak  
callback
        // as those cannot be deallocated until we are back from the  
callback.
        set_first_free(NULL);
+      if (first_deallocated()) {
+        first_deallocated()->set_next(head());
+      }
        // Leaving V8.
        VMState state(EXTERNAL);
        func(object, par);
@@ -270,6 +273,7 @@
      // Next try deallocated list
      result = first_deallocated();
      set_first_deallocated(result->next_free());
+    ASSERT(result->next() == head());
      set_head(result);
    } else {
      // Allocate a new node.
=======================================
--- /branches/1.3/src/heap.cc   Wed Oct 28 07:53:37 2009
+++ /branches/1.3/src/heap.cc   Tue Nov 17 13:43:00 2009
@@ -1730,6 +1730,7 @@
    // Statically ensure that it is safe to allocate proxies in paged spaces.
    STATIC_ASSERT(Proxy::kSize <= Page::kMaxHeapObjectSize);
    AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE :  
NEW_SPACE;
+  if (always_allocate()) space = OLD_DATA_SPACE;
    Object* result = Allocate(proxy_map(), space);
    if (result->IsFailure()) return result;

@@ -1821,12 +1822,13 @@
        : long_cons_string_map();
    }

-  Object* result = Allocate(map, NEW_SPACE);
+  Object* result = Allocate(map,
+                            always_allocate() ? OLD_POINTER_SPACE :  
NEW_SPACE);
    if (result->IsFailure()) return result;
-  ASSERT(InNewSpace(result));
    ConsString* cons_string = ConsString::cast(result);
-  cons_string->set_first(first, SKIP_WRITE_BARRIER);
-  cons_string->set_second(second, SKIP_WRITE_BARRIER);
+  WriteBarrierMode mode = cons_string->GetWriteBarrierMode();
+  cons_string->set_first(first, mode);
+  cons_string->set_second(second, mode);
    cons_string->set_length(length);
    return result;
  }
@@ -1920,7 +1922,8 @@
      map = long_external_ascii_string_map();
    }

-  Object* result = Allocate(map, NEW_SPACE);
+  Object* result = Allocate(map,
+                            always_allocate() ? OLD_DATA_SPACE :  
NEW_SPACE);
    if (result->IsFailure()) return result;

    ExternalAsciiString* external_string = ExternalAsciiString::cast(result);
@@ -1936,7 +1939,8 @@
    int length = resource->length();

    Map* map = ExternalTwoByteString::StringMap(length);
-  Object* result = Allocate(map, NEW_SPACE);
+  Object* result = Allocate(map,
+                            always_allocate() ? OLD_DATA_SPACE :  
NEW_SPACE);
    if (result->IsFailure()) return result;

    ExternalTwoByteString* external_string =  
ExternalTwoByteString::cast(result);
@@ -2321,6 +2325,7 @@
    AllocationSpace space =
        (pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE;
    if (map->instance_size() > MaxObjectSizeInPagedSpace()) space = LO_SPACE;
+  if (always_allocate()) space = OLD_POINTER_SPACE;
    Object* obj = Allocate(map, space);
    if (obj->IsFailure()) return obj;

=======================================
--- /branches/1.3/src/ia32/codegen-ia32.cc      Thu Oct 29 07:46:49 2009
+++ /branches/1.3/src/ia32/codegen-ia32.cc      Tue Nov 17 13:43:00 2009
@@ -3958,12 +3958,28 @@
  }


-void CodeGenerator::LoadUnsafeSmi(Register target, Handle<Object> value) {
+void CodeGenerator::PushUnsafeSmi(Handle<Object> value) {
+  ASSERT(value->IsSmi());
+  int bits = reinterpret_cast<int>(*value);
+  __ push(Immediate(bits & 0x0000FFFF));
+  __ or_(Operand(esp, 0), Immediate(bits & 0xFFFF0000));
+}
+
+
+void CodeGenerator::StoreUnsafeSmiToLocal(int offset, Handle<Object>  
value) {
+  ASSERT(value->IsSmi());
+  int bits = reinterpret_cast<int>(*value);
+  __ mov(Operand(ebp, offset), Immediate(bits & 0x0000FFFF));
+  __ or_(Operand(ebp, offset), Immediate(bits & 0xFFFF0000));
+}
+
+
+void CodeGenerator::MoveUnsafeSmi(Register target, Handle<Object> value) {
    ASSERT(target.is_valid());
    ASSERT(value->IsSmi());
    int bits = reinterpret_cast<int>(*value);
    __ Set(target, Immediate(bits & 0x0000FFFF));
-  __ xor_(target, bits & 0xFFFF0000);
+  __ or_(target, bits & 0xFFFF0000);
  }


=======================================
--- /branches/1.3/src/ia32/codegen-ia32.h       Wed Oct 28 07:53:37 2009
+++ /branches/1.3/src/ia32/codegen-ia32.h       Tue Nov 17 13:43:00 2009
@@ -484,9 +484,11 @@
    // than 16 bits.
    static const int kMaxSmiInlinedBits = 16;
    bool IsUnsafeSmi(Handle<Object> value);
-  // Load an integer constant x into a register target using
+  // Load an integer constant x into a register target or into the stack  
using
    // at most 16 bits of user-controlled data per assembly operation.
-  void LoadUnsafeSmi(Register target, Handle<Object> value);
+  void MoveUnsafeSmi(Register target, Handle<Object> value);
+  void StoreUnsafeSmiToLocal(int offset, Handle<Object> value);
+  void PushUnsafeSmi(Handle<Object> value);

    void CallWithArguments(ZoneList<Expression*>* arguments, int position);

=======================================
--- /branches/1.3/src/ia32/register-allocator-ia32.cc   Wed Sep  9 12:27:10  
2009
+++ /branches/1.3/src/ia32/register-allocator-ia32.cc   Tue Nov 17 13:43:00  
2009
@@ -42,7 +42,7 @@
      Result fresh = CodeGeneratorScope::Current()->allocator()->Allocate();
      ASSERT(fresh.is_valid());
      if (CodeGeneratorScope::Current()->IsUnsafeSmi(handle())) {
-      CodeGeneratorScope::Current()->LoadUnsafeSmi(fresh.reg(), handle());
+      CodeGeneratorScope::Current()->MoveUnsafeSmi(fresh.reg(), handle());
      } else {
        CodeGeneratorScope::Current()->masm()->Set(fresh.reg(),
                                                   Immediate(handle()));
@@ -64,7 +64,7 @@
      } else {
        ASSERT(is_constant());
        if (CodeGeneratorScope::Current()->IsUnsafeSmi(handle())) {
-        CodeGeneratorScope::Current()->LoadUnsafeSmi(fresh.reg(),  
handle());
+        CodeGeneratorScope::Current()->MoveUnsafeSmi(fresh.reg(),  
handle());
        } else {
          CodeGeneratorScope::Current()->masm()->Set(fresh.reg(),
                                                     Immediate(handle()));
=======================================
--- /branches/1.3/src/ia32/virtual-frame-ia32.cc        Wed Nov 11 01:17:04 2009
+++ /branches/1.3/src/ia32/virtual-frame-ia32.cc        Tue Nov 17 13:43:00 2009
@@ -75,10 +75,7 @@

      case FrameElement::CONSTANT:
        if (cgen()->IsUnsafeSmi(element.handle())) {
-        Result temp = cgen()->allocator()->Allocate();
-        ASSERT(temp.is_valid());
-        cgen()->LoadUnsafeSmi(temp.reg(), element.handle());
-        __ mov(Operand(ebp, fp_relative(index)), temp.reg());
+        cgen()->StoreUnsafeSmiToLocal(fp_relative(index),  
element.handle());
        } else {
          __ Set(Operand(ebp, fp_relative(index)),
                 Immediate(element.handle()));
@@ -127,10 +124,7 @@

      case FrameElement::CONSTANT:
        if (cgen()->IsUnsafeSmi(element.handle())) {
-        Result temp = cgen()->allocator()->Allocate();
-        ASSERT(temp.is_valid());
-        cgen()->LoadUnsafeSmi(temp.reg(), element.handle());
-        __ push(temp.reg());
+       cgen()->PushUnsafeSmi(element.handle());
        } else {
          __ push(Immediate(element.handle()));
        }
@@ -161,15 +155,16 @@
    // on the stack.
    int start = Min(begin, stack_pointer_ + 1);

-  // If positive we have to adjust the stack pointer.
-  int delta = end - stack_pointer_;
-  if (delta > 0) {
-    stack_pointer_ = end;
-    __ sub(Operand(esp), Immediate(delta * kPointerSize));
-  }
-
+  // Emit normal push instructions for elements above stack pointer
+  // and use mov instructions if we are below stack pointer.
    for (int i = start; i <= end; i++) {
-    if (!elements_[i].is_synced()) SyncElementBelowStackPointer(i);
+    if (!elements_[i].is_synced()) {
+      if (i <= stack_pointer_) {
+        SyncElementBelowStackPointer(i);
+      } else {
+        SyncElementByPushing(i);
+      }
+    }
    }
  }

@@ -198,7 +193,7 @@
          // Emit a move.
          if (element.is_constant()) {
            if (cgen()->IsUnsafeSmi(element.handle())) {
-            cgen()->LoadUnsafeSmi(fresh.reg(), element.handle());
+            cgen()->MoveUnsafeSmi(fresh.reg(), element.handle());
            } else {
              __ Set(fresh.reg(), Immediate(element.handle()));
            }
@@ -299,7 +294,7 @@
            if (!source.is_synced()) {
              if (cgen()->IsUnsafeSmi(source.handle())) {
                esi_caches = i;
-              cgen()->LoadUnsafeSmi(esi, source.handle());
+              cgen()->MoveUnsafeSmi(esi, source.handle());
                __ mov(Operand(ebp, fp_relative(i)), esi);
              } else {
                __ Set(Operand(ebp, fp_relative(i)),  
Immediate(source.handle()));
@@ -407,7 +402,7 @@

          case FrameElement::CONSTANT:
            if (cgen()->IsUnsafeSmi(source.handle())) {
-            cgen()->LoadUnsafeSmi(target_reg, source.handle());
+            cgen()->MoveUnsafeSmi(target_reg, source.handle());
            } else {
             __ Set(target_reg, Immediate(source.handle()));
            }
=======================================
--- /branches/1.3/src/runtime.cc        Wed Nov 11 02:11:16 2009
+++ /branches/1.3/src/runtime.cc        Tue Nov 17 13:43:00 2009
@@ -4336,8 +4336,6 @@

    Object* result = Heap::AllocateArgumentsObject(callee, length);
    if (result->IsFailure()) return result;
-  ASSERT(Heap::InNewSpace(result));
-
    // Allocate the elements if needed.
    if (length > 0) {
      // Allocate the fixed array.
@@ -4350,8 +4348,7 @@
      for (int i = 0; i < length; i++) {
        array->set(i, *--parameters, mode);
      }
-    JSObject::cast(result)->set_elements(FixedArray::cast(obj),
-                                         SKIP_WRITE_BARRIER);
+    JSObject::cast(result)->set_elements(FixedArray::cast(obj));
    }
    return result;
  }
=======================================
--- /branches/1.3/src/version.cc        Tue Nov 17 01:53:59 2009
+++ /branches/1.3/src/version.cc        Tue Nov 17 13:43:00 2009
@@ -35,7 +35,7 @@
  #define MAJOR_VERSION     1
  #define MINOR_VERSION     3
  #define BUILD_NUMBER      18
-#define PATCH_LEVEL       9
+#define PATCH_LEVEL       10
  #define CANDIDATE_VERSION false

  // Define SONAME to have the SCons build the put a specific SONAME into the
=======================================
--- /branches/1.3/test/cctest/test-api.cc       Fri Nov 13 00:04:17 2009
+++ /branches/1.3/test/cctest/test-api.cc       Tue Nov 17 13:43:00 2009
@@ -6450,6 +6450,31 @@
    to_be_disposed = handle2;
    i::Heap::CollectAllGarbage(false);
  }
+
+void DisposingCallback(v8::Persistent<v8::Value> handle, void*) {
+  handle.Dispose();
+}
+
+void HandleCreatingCallback(v8::Persistent<v8::Value> handle, void*) {
+  v8::HandleScope scope;
+  v8::Persistent<v8::Object>::New(v8::Object::New());
+}
+
+
+THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) {
+  LocalContext context;
+
+  v8::Persistent<v8::Object> handle1, handle2, handle3;
+  {
+    v8::HandleScope scope;
+    handle3 = v8::Persistent<v8::Object>::New(v8::Object::New());
+    handle2 = v8::Persistent<v8::Object>::New(v8::Object::New());
+    handle1 = v8::Persistent<v8::Object>::New(v8::Object::New());
+  }
+  handle2.MakeWeak(NULL, DisposingCallback);
+  handle3.MakeWeak(NULL, HandleCreatingCallback);
+  i::Heap::CollectAllGarbage(false);
+}


  THREADED_TEST(CheckForCrossContextObjectLiterals) {

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

Reply via email to