Revision: 22725
Author:   [email protected]
Date:     Thu Jul 31 00:04:39 2014 UTC
Log:      Version 3.28.50 (based on bleeding_edge revision r22696)

Use emergency memory in the case of out of memory during evacuation (Chromium issue 395314).

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

Modified:
 /trunk/ChangeLog
 /trunk/src/mark-compact.cc
 /trunk/src/spaces.cc
 /trunk/src/spaces.h
 /trunk/src/version.cc
 /trunk/src/x87/code-stubs-x87.cc
 /trunk/src/x87/ic-x87.cc
 /trunk/src/x87/lithium-codegen-x87.cc
 /trunk/src/x87/lithium-x87.cc
 /trunk/src/x87/lithium-x87.h
 /trunk/src/x87/macro-assembler-x87.cc
 /trunk/src/x87/stub-cache-x87.cc

=======================================
--- /trunk/ChangeLog    Wed Jul 30 00:05:07 2014 UTC
+++ /trunk/ChangeLog    Thu Jul 31 00:04:39 2014 UTC
@@ -1,3 +1,11 @@
+2014-07-31: Version 3.28.50
+
+        Use emergency memory in the case of out of memory during evacuation
+        (Chromium issue 395314).
+
+        Performance and stability improvements on all platforms.
+
+
 2014-07-30: Version 3.28.48

Fix Object.freeze with field type tracking. Keep the descriptor properly
=======================================
--- /trunk/src/mark-compact.cc  Thu Jul 24 00:04:58 2014 UTC
+++ /trunk/src/mark-compact.cc  Thu Jul 31 00:04:39 2014 UTC
@@ -3105,6 +3105,12 @@

       HeapObject* target_object;
       AllocationResult allocation = space->AllocateRaw(size);
+      if (!allocation.To(&target_object)) {
+ // If allocation failed, use emergency memory and re-try allocation.
+        CHECK(space->HasEmergencyMemory());
+        space->UseEmergencyMemory();
+        allocation = space->AllocateRaw(size);
+      }
       if (!allocation.To(&target_object)) {
         // OS refused to give us memory.
         V8::FatalProcessOutOfMemory("Evacuation");
@@ -3130,10 +3136,16 @@
            p->IsFlagSet(Page::RESCAN_ON_EVACUATION));
     ASSERT(static_cast<int>(p->parallel_sweeping()) ==
            MemoryChunk::SWEEPING_DONE);
+    PagedSpace* space = static_cast<PagedSpace*>(p->owner());
+ // Allocate emergency memory for the case when compaction fails due to out
+    // of memory.
+    if (!space->HasEmergencyMemory()) {
+      space->CreateEmergencyMemory();
+    }
     if (p->IsEvacuationCandidate()) {
-      // During compaction we might have to request a new page.
-      // Check that space still have room for that.
-      if (static_cast<PagedSpace*>(p->owner())->CanExpand()) {
+ // During compaction we might have to request a new page. Check that we
+      // have an emergency page and the space still has room for that.
+      if (space->HasEmergencyMemory() && space->CanExpand()) {
         EvacuateLiveObjectsFromPage(p);
       } else {
// Without room for expansion evacuation is not guaranteed to succeed.
@@ -3144,7 +3156,17 @@
           page->ClearEvacuationCandidate();
           page->SetFlag(Page::RESCAN_ON_EVACUATION);
         }
-        return;
+        break;
+      }
+    }
+  }
+  if (npages > 0) {
+    // Release emergency memory.
+    PagedSpaces spaces(heap());
+    for (PagedSpace* space = spaces.next(); space != NULL;
+         space = spaces.next()) {
+      if (space->HasEmergencyMemory()) {
+        space->FreeEmergencyMemory();
       }
     }
   }
=======================================
--- /trunk/src/spaces.cc        Tue Jul 29 08:45:47 2014 UTC
+++ /trunk/src/spaces.cc        Thu Jul 31 00:04:39 2014 UTC
@@ -929,15 +929,14 @@
// -----------------------------------------------------------------------------
 // PagedSpace implementation

-PagedSpace::PagedSpace(Heap* heap,
-                       intptr_t max_capacity,
-                       AllocationSpace id,
+PagedSpace::PagedSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id,
                        Executability executable)
     : Space(heap, id, executable),
       free_list_(this),
       swept_precisely_(true),
       unswept_free_bytes_(0),
-      end_of_unswept_pages_(NULL) {
+      end_of_unswept_pages_(NULL),
+      emergency_memory_(NULL) {
   if (id == CODE_SPACE) {
     area_size_ = heap->isolate()->memory_allocator()->
         CodePageAreaSize();
@@ -1148,6 +1147,29 @@
   ASSERT(Capacity() > 0);
   accounting_stats_.ShrinkSpace(AreaSize());
 }
+
+
+void PagedSpace::CreateEmergencyMemory() {
+  emergency_memory_ = heap()->isolate()->memory_allocator()->AllocateChunk(
+      AreaSize(), AreaSize(), executable(), this);
+}
+
+
+void PagedSpace::FreeEmergencyMemory() {
+  Page* page = static_cast<Page*>(emergency_memory_);
+  ASSERT(page->LiveBytes() == 0);
+  ASSERT(AreaSize() == page->area_size());
+  ASSERT(!free_list_.ContainsPageFreeListItems(page));
+  heap()->isolate()->memory_allocator()->Free(page);
+  emergency_memory_ = NULL;
+}
+
+
+void PagedSpace::UseEmergencyMemory() {
+ Page* page = Page::Initialize(heap(), emergency_memory_, executable(), this);
+  page->InsertAfter(anchor_.prev_page());
+  emergency_memory_ = NULL;
+}


 #ifdef DEBUG
=======================================
--- /trunk/src/spaces.h Tue Jul 29 08:45:47 2014 UTC
+++ /trunk/src/spaces.h Thu Jul 31 00:04:39 2014 UTC
@@ -1979,6 +1979,12 @@
   inline int AreaSize() {
     return area_size_;
   }
+
+  void CreateEmergencyMemory();
+  void FreeEmergencyMemory();
+  void UseEmergencyMemory();
+
+  bool HasEmergencyMemory() { return emergency_memory_ != NULL; }

  protected:
   FreeList* free_list() { return &free_list_; }
@@ -2015,6 +2021,12 @@
   // end_of_unswept_pages_ page.
   Page* end_of_unswept_pages_;

+ // Emergency memory is the memory of a full page for a given space, allocated + // conservatively before evacuating a page. If compaction fails due to out + // of memory error the emergency memory can be used to complete compaction.
+  // If not used, the emergency memory is released after compaction.
+  MemoryChunk* emergency_memory_;
+
// Expands the space by allocating a fixed number of pages. Returns false if // it cannot allocate requested number of pages from OS, or if the hard heap
   // size limit has been hit.
=======================================
--- /trunk/src/version.cc       Wed Jul 30 00:05:07 2014 UTC
+++ /trunk/src/version.cc       Thu Jul 31 00:04:39 2014 UTC
@@ -34,7 +34,7 @@
 // system so their names cannot be changed without changing the scripts.
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     28
-#define BUILD_NUMBER      48
+#define BUILD_NUMBER      50
 #define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
=======================================
--- /trunk/src/x87/code-stubs-x87.cc    Tue Jul 29 08:45:47 2014 UTC
+++ /trunk/src/x87/code-stubs-x87.cc    Thu Jul 31 00:04:39 2014 UTC
@@ -2049,10 +2049,16 @@
   __ j(not_equal, &miss);

   __ mov(eax, arg_count());
-  __ mov(ebx, FieldOperand(ebx, edx, times_half_pointer_size,
+  __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size,
                            FixedArray::kHeaderSize));
+
   // Verify that ecx contains an AllocationSite
-  __ AssertUndefinedOrAllocationSite(ebx);
+  Factory* factory = masm->isolate()->factory();
+  __ cmp(FieldOperand(ecx, HeapObject::kMapOffset),
+         factory->allocation_site_map());
+  __ j(not_equal, &miss);
+
+  __ mov(ebx, ecx);
   ArrayConstructorStub stub(masm->isolate(), arg_count());
   __ TailCallStub(&stub);

@@ -2123,7 +2129,11 @@
   __ j(equal, &miss);

   if (!FLAG_trace_ic) {
-    // We are going megamorphic, and we don't want to visit the runtime.
+ // We are going megamorphic. If the feedback is a JSFunction, it is fine
+    // to handle it here. More complex cases are dealt with in the runtime.
+    __ AssertNotSmi(ecx);
+    __ CmpObjectType(ecx, JS_FUNCTION_TYPE, ecx);
+    __ j(not_equal, &miss);
     __ mov(FieldOperand(ebx, edx, times_half_pointer_size,
                         FixedArray::kHeaderSize),
            Immediate(TypeFeedbackInfo::MegamorphicSentinel(isolate)));
=======================================
--- /trunk/src/x87/ic-x87.cc    Thu Jul 24 00:04:58 2014 UTC
+++ /trunk/src/x87/ic-x87.cc    Thu Jul 31 00:04:39 2014 UTC
@@ -579,9 +579,8 @@
   __ push(scratch);   // return address

   // Perform tail call to the entry.
-  ExternalReference ref =
-      ExternalReference(IC_Utility(kKeyedLoadPropertyWithInterceptor),
-                        masm->isolate());
+  ExternalReference ref = ExternalReference(
+      IC_Utility(kLoadElementWithInterceptor), masm->isolate());
   __ TailCallExternalReference(ref, 2, 1);

   __ bind(&slow);
=======================================
--- /trunk/src/x87/lithium-codegen-x87.cc       Fri Jul 25 00:05:16 2014 UTC
+++ /trunk/src/x87/lithium-codegen-x87.cc       Thu Jul 31 00:04:39 2014 UTC
@@ -3732,6 +3732,11 @@
 void LCodeGen::DoMathRound(LMathRound* instr) {
   UNIMPLEMENTED();
 }
+
+
+void LCodeGen::DoMathFround(LMathFround* instr) {
+  UNIMPLEMENTED();
+}


 void LCodeGen::DoMathSqrt(LMathSqrt* instr) {
=======================================
--- /trunk/src/x87/lithium-x87.cc       Thu Jul 24 00:04:58 2014 UTC
+++ /trunk/src/x87/lithium-x87.cc       Thu Jul 31 00:04:39 2014 UTC
@@ -1148,6 +1148,7 @@
   switch (instr->op()) {
     case kMathFloor: return DoMathFloor(instr);
     case kMathRound: return DoMathRound(instr);
+    case kMathFround: return DoMathFround(instr);
     case kMathAbs: return DoMathAbs(instr);
     case kMathLog: return DoMathLog(instr);
     case kMathExp: return DoMathExp(instr);
@@ -1173,6 +1174,13 @@
   UNREACHABLE();
   return NULL;
 }
+
+
+LInstruction* LChunkBuilder::DoMathFround(HUnaryMathOperation* instr) {
+  LOperand* input = UseRegisterAtStart(instr->value());
+  LMathFround* result = new (zone()) LMathFround(input);
+  return AssignEnvironment(DefineAsRegister(result));
+}


 LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) {
=======================================
--- /trunk/src/x87/lithium-x87.h        Thu Jul 24 00:04:58 2014 UTC
+++ /trunk/src/x87/lithium-x87.h        Thu Jul 31 00:04:39 2014 UTC
@@ -112,6 +112,7 @@
   V(MathClz32)                                  \
   V(MathExp)                                    \
   V(MathFloor)                                  \
+  V(MathFround)                                 \
   V(MathLog)                                    \
   V(MathMinMax)                                 \
   V(MathPowHalf)                                \
@@ -873,6 +874,16 @@
 };


+class LMathFround V8_FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LMathFround(LOperand* value) { inputs_[0] = value; }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(MathFround, "math-fround")
+};
+
+
 class LMathAbs V8_FINAL : public LTemplateInstruction<1, 2, 0> {
  public:
   LMathAbs(LOperand* context, LOperand* value) {
@@ -2751,6 +2762,7 @@

   LInstruction* DoMathFloor(HUnaryMathOperation* instr);
   LInstruction* DoMathRound(HUnaryMathOperation* instr);
+  LInstruction* DoMathFround(HUnaryMathOperation* instr);
   LInstruction* DoMathAbs(HUnaryMathOperation* instr);
   LInstruction* DoMathLog(HUnaryMathOperation* instr);
   LInstruction* DoMathExp(HUnaryMathOperation* instr);
=======================================
--- /trunk/src/x87/macro-assembler-x87.cc       Wed Jul 30 00:05:07 2014 UTC
+++ /trunk/src/x87/macro-assembler-x87.cc       Thu Jul 31 00:04:39 2014 UTC
@@ -1173,7 +1173,7 @@


// Compute the hash code from the untagged key. This must be kept in sync with
-// ComputeIntegerHash in utils.h and KeyedLoadGenericElementStub in
+// ComputeIntegerHash in utils.h and KeyedLoadGenericStub in
 // code-stub-hydrogen.cc
 //
 // Note: r0 will contain hash code
=======================================
--- /trunk/src/x87/stub-cache-x87.cc    Tue Jul 29 08:45:47 2014 UTC
+++ /trunk/src/x87/stub-cache-x87.cc    Thu Jul 31 00:04:39 2014 UTC
@@ -264,11 +264,11 @@
                                      Register holder,
                                      Register name,
                                      Handle<JSObject> holder_obj) {
-  STATIC_ASSERT(StubCache::kInterceptorArgsNameIndex == 0);
-  STATIC_ASSERT(StubCache::kInterceptorArgsInfoIndex == 1);
-  STATIC_ASSERT(StubCache::kInterceptorArgsThisIndex == 2);
-  STATIC_ASSERT(StubCache::kInterceptorArgsHolderIndex == 3);
-  STATIC_ASSERT(StubCache::kInterceptorArgsLength == 4);
+  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0);
+  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1);
+  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 2);
+ STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 3);
+  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 4);
   __ push(name);
   Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor());
   ASSERT(!masm->isolate()->heap()->InNewSpace(*interceptor));
@@ -288,9 +288,8 @@
     Handle<JSObject> holder_obj,
     IC::UtilityId id) {
   PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
-  __ CallExternalReference(
-      ExternalReference(IC_Utility(id), masm->isolate()),
-      StubCache::kInterceptorArgsLength);
+ __ CallExternalReference(ExternalReference(IC_Utility(id), masm->isolate()), + NamedLoadHandlerCompiler::kInterceptorArgsLength);
 }


@@ -1035,7 +1034,8 @@
     ExternalReference ref =
         ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptor),
                           isolate());
- __ TailCallExternalReference(ref, StubCache::kInterceptorArgsLength, 1);
+    __ TailCallExternalReference(
+        ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
   }
 }

@@ -1122,8 +1122,8 @@
   __ push(scratch1());  // restore return address

   // Do tail-call to the runtime system.
-  ExternalReference store_ic_property =
- ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate());
+  ExternalReference store_ic_property = ExternalReference(
+      IC_Utility(IC::kStorePropertyWithInterceptor), isolate());
   __ TailCallExternalReference(store_ic_property, 3, 1);

   // Return the generated code.
@@ -1145,7 +1145,7 @@
 }


-Handle<Code> PropertyICCompiler::CompileIndexedStorePolymorphic(
+Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
     MapHandleList* receiver_maps, CodeHandleList* handler_stubs,
     MapHandleList* transitioned_maps) {
   Label miss;
@@ -1343,7 +1343,7 @@
 #define __ ACCESS_MASM(masm)


-void IndexedHandlerCompiler::GenerateLoadDictionaryElement(
+void ElementHandlerCompiler::GenerateLoadDictionaryElement(
     MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- ecx    : key

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