Stop inlining of list reallocation in virtual frames.
authorwhesse@chromium.org <whesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 1 May 2009 14:37:28 +0000 (14:37 +0000)
committerwhesse@chromium.org <whesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 1 May 2009 14:37:28 +0000 (14:37 +0000)
Review URL: http://codereview.chromium.org/100253

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1835 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/list-inl.h
src/list.h
src/virtual-frame.cc

index 6dbd214d737026cdcd1f167f98a491a3279462ff..e3d251fba5ceb91a731a8a014246a472a9538a68 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2006-2009 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:
@@ -38,21 +38,36 @@ void List<T, P>::Add(const T& element) {
   if (length_ < capacity_) {
     data_[length_++] = element;
   } else {
-    // Grow the list capacity by 50%, but make sure to let it grow
-    // even when the capacity is zero (possible initial case).
-    int new_capacity = 1 + capacity_ + (capacity_ >> 1);
-    T* new_data = NewData(new_capacity);
-    memcpy(new_data, data_, capacity_ * sizeof(T));
-    // Since the element reference could be an element of the list,
-    // assign it to the new backing store before deleting the old.
-    new_data[length_++] = element;
-    DeleteData(data_);
-    data_ = new_data;
-    capacity_ = new_capacity;
+    List<T, P>::ResizeAdd(element);
   }
 }
 
 
+// Use two layers of inlining so that the non-inlined function can
+// use the same implementation as the inlined version.
+template<typename T, class P>
+void List<T, P>::ResizeAdd(const T& element) {
+  ResizeAddInternal(element);
+}
+
+
+template<typename T, class P>
+void List<T, P>::ResizeAddInternal(const T& element) {
+  ASSERT(length_ >= capacity_);
+  // Grow the list capacity by 50%, but make sure to let it grow
+  // even when the capacity is zero (possible initial case).
+  int new_capacity = 1 + capacity_ + (capacity_ >> 1);
+  T* new_data = List<T, P>::NewData(new_capacity);
+  memcpy(new_data, data_, capacity_ * sizeof(T));
+  // Since the element reference could be an element of the list,
+  // assign it to the new backing store before deleting the old.
+  new_data[length_++] = element;
+  List<T, P>::DeleteData(data_);
+  data_ = new_data;
+  capacity_ = new_capacity;
+}
+
+
 template<typename T, class P>
 Vector<T> List<T, P>::AddBlock(T value, int count) {
   int start = length_;
index dc2f1158d3a4957725377fccaec31bba3515a069..92d23ea391e557192cdabf1254209fd4dbab6e4a 100644 (file)
@@ -118,9 +118,24 @@ class List {
   INLINE(T* NewData(int n))  { return static_cast<T*>(P::New(n * sizeof(T))); }
   INLINE(void DeleteData(T* data))  { P::Delete(data); }
 
+  // Increase the capacity of a full list, and add an element.
+  // List must be full already.
+  void ResizeAdd(const T& element);
+
+  // Inlined implementation of ResizeAdd, shared by inlined and
+  // non-inlined versions of ResizeAdd.
+  void ResizeAddInternal(const T& element);
+
   DISALLOW_COPY_AND_ASSIGN(List);
 };
 
+class FrameElement;
+
+// Add() is inlined, ResizeAdd() called by Add() is inlined except for
+// Lists of FrameElements, and ResizeAddInternal() is inlined in ResizeAdd().
+template <>
+void List<FrameElement,
+          FreeStoreAllocationPolicy>::ResizeAdd(const FrameElement& element);
 
 } }  // namespace v8::internal
 
index cef1d80732d81869c4bf6d3c17df76e747de0f16..566fcdbc0e071d36530c841bec205edf5bea3313 100644 (file)
@@ -507,4 +507,14 @@ bool VirtualFrame::Equals(VirtualFrame* other) {
   return true;
 }
 
+
+// Specialization of List::ResizeAdd to non-inlined version for FrameElements.
+// The function ResizeAdd becomes a real function, whose implementation is the
+// inlined ResizeAddInternal.
+template <>
+void List<FrameElement,
+          FreeStoreAllocationPolicy>::ResizeAdd(const FrameElement& element) {
+  ResizeAddInternal(element);
+}
+
 } }  // namespace v8::internal