Revision: 4706
Author: [email protected]
Date: Fri May 21 22:27:19 2010
Log: CPU profiler: make code events handling scalable.

I changed the implementation of a queue between the VM and processor
thread to be unbounded and lock-free, using Herb Sutter's example from
DDJ article: http://www.ddj.com/high-performance-computing/210604448
This had brought back profiling overhead to a minimum for the page
from Chromium's issue 16184.

BUG=714

Review URL: http://codereview.chromium.org/2091019
http://code.google.com/p/v8/source/detail?r=4706

Added:
 /branches/bleeding_edge/src/unbound-queue-inl.h
 /branches/bleeding_edge/src/unbound-queue.h
 /branches/bleeding_edge/test/cctest/test-unbound-queue.cc
Modified:
 /branches/bleeding_edge/src/circular-queue-inl.h
 /branches/bleeding_edge/src/circular-queue.h
 /branches/bleeding_edge/src/cpu-profiler-inl.h
 /branches/bleeding_edge/src/cpu-profiler.cc
 /branches/bleeding_edge/src/cpu-profiler.h
 /branches/bleeding_edge/src/platform-linux.cc
 /branches/bleeding_edge/src/platform-macos.cc
 /branches/bleeding_edge/src/platform-win32.cc
 /branches/bleeding_edge/src/platform.h
 /branches/bleeding_edge/src/v8.cc
 /branches/bleeding_edge/test/cctest/SConscript
 /branches/bleeding_edge/test/cctest/test-circular-queue.cc
 /branches/bleeding_edge/tools/gyp/v8.gyp
 /branches/bleeding_edge/tools/v8.xcodeproj/project.pbxproj
 /branches/bleeding_edge/tools/visual_studio/v8_base.vcproj
 /branches/bleeding_edge/tools/visual_studio/v8_base_arm.vcproj
 /branches/bleeding_edge/tools/visual_studio/v8_base_x64.vcproj
 /branches/bleeding_edge/tools/visual_studio/v8_cctest.vcproj

=======================================
--- /dev/null
+++ /branches/bleeding_edge/src/unbound-queue-inl.h     Fri May 21 22:27:19 2010
@@ -0,0 +1,87 @@
+// Copyright 2010 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.
+
+#ifndef V8_UNBOUND_QUEUE_INL_H_
+#define V8_UNBOUND_QUEUE_INL_H_
+
+#include "unbound-queue.h"
+
+namespace v8 {
+namespace internal {
+
+template<typename Record>
+struct UnboundQueue<Record>::Node: public Malloced {
+  explicit Node(const Record& value)
+      : value(value), next(NULL) {
+  }
+
+  Record value;
+  Node* next;
+};
+
+
+template<typename Record>
+UnboundQueue<Record>::UnboundQueue() {
+  first_ = new Node(Record());
+  divider_ = last_ = reinterpret_cast<AtomicWord>(first_);
+}
+
+
+template<typename Record>
+UnboundQueue<Record>::~UnboundQueue() {
+  while (first_ != NULL) DeleteFirst();
+}
+
+
+template<typename Record>
+void UnboundQueue<Record>::DeleteFirst() {
+  Node* tmp = first_;
+  first_ = tmp->next;
+  delete tmp;
+}
+
+
+template<typename Record>
+void UnboundQueue<Record>::Dequeue(Record* rec) {
+  ASSERT(divider_ != last_);
+  Node* next = reinterpret_cast<Node*>(divider_)->next;
+  *rec = next->value;
+  OS::ReleaseStore(&divider_, reinterpret_cast<AtomicWord>(next));
+}
+
+
+template<typename Record>
+void UnboundQueue<Record>::Enqueue(const Record& rec) {
+  Node*& next = reinterpret_cast<Node*>(last_)->next;
+  next = new Node(rec);
+  OS::ReleaseStore(&last_, reinterpret_cast<AtomicWord>(next));
+  while (first_ != reinterpret_cast<Node*>(divider_)) DeleteFirst();
+}
+
+} }  // namespace v8::internal
+
+#endif  // V8_UNBOUND_QUEUE_INL_H_
=======================================
--- /dev/null
+++ /branches/bleeding_edge/src/unbound-queue.h Fri May 21 22:27:19 2010
@@ -0,0 +1,66 @@
+// Copyright 2010 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.
+
+#ifndef V8_UNBOUND_QUEUE_
+#define V8_UNBOUND_QUEUE_
+
+namespace v8 {
+namespace internal {
+
+
+// Lock-free unbound queue for small records.  Intended for
+// transferring small records between a Single producer and a Single
+// consumer. Doesn't have restrictions on the number of queued
+// elements, so producer never blocks.  Implemented after Herb
+// Sutter's article:
+// http://www.ddj.com/high-performance-computing/210604448
+template<typename Record>
+class UnboundQueue BASE_EMBEDDED {
+ public:
+  inline UnboundQueue();
+  inline ~UnboundQueue();
+
+  INLINE(void Dequeue(Record* rec));
+  INLINE(void Enqueue(const Record& rec));
+  INLINE(bool IsEmpty()) { return divider_ == last_; }
+
+ private:
+  INLINE(void DeleteFirst());
+
+  struct Node;
+
+  Node* first_;
+  AtomicWord divider_;  // Node*
+  AtomicWord last_;     // Node*
+
+  DISALLOW_COPY_AND_ASSIGN(UnboundQueue);
+};
+
+
+} }  // namespace v8::internal
+
+#endif  // V8_UNBOUND_QUEUE_
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/cctest/test-unbound-queue.cc Fri May 21 22:27:19 2010
@@ -0,0 +1,54 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+//
+// Tests of the unbound queue.
+
+#include "v8.h"
+#include "unbound-queue-inl.h"
+#include "cctest.h"
+
+namespace i = v8::internal;
+
+using i::UnboundQueue;
+
+
+TEST(SingleRecord) {
+  typedef int Record;
+  UnboundQueue<Record> cq;
+  CHECK(cq.IsEmpty());
+  cq.Enqueue(1);
+  CHECK(!cq.IsEmpty());
+  Record rec = 0;
+  cq.Dequeue(&rec);
+  CHECK_EQ(1, rec);
+  CHECK(cq.IsEmpty());
+}
+
+
+TEST(MultipleRecords) {
+  typedef int Record;
+  UnboundQueue<Record> cq;
+  CHECK(cq.IsEmpty());
+  cq.Enqueue(1);
+  CHECK(!cq.IsEmpty());
+  for (int i = 2; i <= 5; ++i) {
+    cq.Enqueue(i);
+    CHECK(!cq.IsEmpty());
+  }
+  Record rec = 0;
+  for (int i = 1; i <= 4; ++i) {
+    CHECK(!cq.IsEmpty());
+    cq.Dequeue(&rec);
+    CHECK_EQ(i, rec);
+  }
+  for (int i = 6; i <= 12; ++i) {
+    cq.Enqueue(i);
+    CHECK(!cq.IsEmpty());
+  }
+  for (int i = 5; i <= 12; ++i) {
+    CHECK(!cq.IsEmpty());
+    cq.Dequeue(&rec);
+    CHECK_EQ(i, rec);
+  }
+  CHECK(cq.IsEmpty());
+}
+
=======================================
--- /branches/bleeding_edge/src/circular-queue-inl.h Tue Apr 13 04:59:37 2010 +++ /branches/bleeding_edge/src/circular-queue-inl.h Fri May 21 22:27:19 2010
@@ -32,54 +32,6 @@

 namespace v8 {
 namespace internal {
-
-
-template<typename Record>
-CircularQueue<Record>::CircularQueue(int desired_buffer_size_in_bytes)
- : buffer_(NewArray<Record>(desired_buffer_size_in_bytes / sizeof(Record))),
-      buffer_end_(buffer_ + desired_buffer_size_in_bytes / sizeof(Record)),
-      enqueue_semaphore_(
- OS::CreateSemaphore(static_cast<int>(buffer_end_ - buffer_) - 1)),
-      enqueue_pos_(buffer_),
-      dequeue_pos_(buffer_) {
-  // To be able to distinguish between a full and an empty queue
-  // state, the queue must be capable of containing at least 2
-  // records.
-  ASSERT((buffer_end_ - buffer_) >= 2);
-}
-
-
-template<typename Record>
-CircularQueue<Record>::~CircularQueue() {
-  DeleteArray(buffer_);
-  delete enqueue_semaphore_;
-}
-
-
-template<typename Record>
-void CircularQueue<Record>::Dequeue(Record* rec) {
-  ASSERT(!IsEmpty());
-  *rec = *dequeue_pos_;
-  dequeue_pos_ = Next(dequeue_pos_);
-  // Tell we have a spare record.
-  enqueue_semaphore_->Signal();
-}
-
-
-template<typename Record>
-void CircularQueue<Record>::Enqueue(const Record& rec) {
-  // Wait until we have at least one spare record.
-  enqueue_semaphore_->Wait();
-  ASSERT(Next(enqueue_pos_) != dequeue_pos_);
-  *enqueue_pos_ = rec;
-  enqueue_pos_ = Next(enqueue_pos_);
-}
-
-
-template<typename Record>
-Record* CircularQueue<Record>::Next(Record* curr) {
-  return ++curr != buffer_end_ ? curr : buffer_;
-}


 void* SamplingCircularQueue::Enqueue() {
=======================================
--- /branches/bleeding_edge/src/circular-queue.h        Tue Mar 30 04:38:39 2010
+++ /branches/bleeding_edge/src/circular-queue.h        Fri May 21 22:27:19 2010
@@ -32,32 +32,6 @@
 namespace internal {


-// Lock-based blocking circular queue for small records.  Intended for
-// transfer of small records between a single producer and a single
-// consumer. Blocks on enqueue operation if the queue is full.
-template<typename Record>
-class CircularQueue {
- public:
-  inline explicit CircularQueue(int desired_buffer_size_in_bytes);
-  inline ~CircularQueue();
-
-  INLINE(void Dequeue(Record* rec));
-  INLINE(void Enqueue(const Record& rec));
-  INLINE(bool IsEmpty()) { return enqueue_pos_ == dequeue_pos_; }
-
- private:
-  INLINE(Record* Next(Record* curr));
-
-  Record* buffer_;
-  Record* const buffer_end_;
-  Semaphore* enqueue_semaphore_;
-  Record* enqueue_pos_;
-  Record* dequeue_pos_;
-
-  DISALLOW_COPY_AND_ASSIGN(CircularQueue);
-};
-
-
 // Lock-free cache-friendly sampling circular queue for large
 // records. Intended for fast transfer of large records between a
 // single producer and a single consumer. If the queue is full,
=======================================
--- /branches/bleeding_edge/src/cpu-profiler-inl.h      Tue May 18 07:19:33 2010
+++ /branches/bleeding_edge/src/cpu-profiler-inl.h      Fri May 21 22:27:19 2010
@@ -34,6 +34,7 @@

 #include "circular-queue-inl.h"
 #include "profile-generator-inl.h"
+#include "unbound-queue-inl.h"

 namespace v8 {
 namespace internal {
=======================================
--- /branches/bleeding_edge/src/cpu-profiler.cc Tue May 18 07:19:33 2010
+++ /branches/bleeding_edge/src/cpu-profiler.cc Fri May 21 22:27:19 2010
@@ -46,7 +46,6 @@
ProfilerEventsProcessor::ProfilerEventsProcessor(ProfileGenerator* generator)
     : generator_(generator),
       running_(false),
-      events_buffer_(kEventsBufferSize),
       ticks_buffer_(sizeof(TickSampleEventRecord),
                     kTickSamplesBufferChunkSize,
                     kTickSamplesBufferChunksCount),
=======================================
--- /branches/bleeding_edge/src/cpu-profiler.h  Tue May 18 07:19:33 2010
+++ /branches/bleeding_edge/src/cpu-profiler.h  Fri May 21 22:27:19 2010
@@ -31,6 +31,7 @@
 #ifdef ENABLE_LOGGING_AND_PROFILING

 #include "circular-queue.h"
+#include "unbound-queue.h"

 namespace v8 {
 namespace internal {
@@ -181,7 +182,7 @@

   ProfileGenerator* generator_;
   bool running_;
-  CircularQueue<CodeEventsContainer> events_buffer_;
+  UnboundQueue<CodeEventsContainer> events_buffer_;
   SamplingCircularQueue ticks_buffer_;
   unsigned enqueue_order_;
 };
=======================================
--- /branches/bleeding_edge/src/platform-linux.cc       Wed May  5 05:25:58 2010
+++ /branches/bleeding_edge/src/platform-linux.cc       Fri May 21 22:27:19 2010
@@ -163,6 +163,28 @@
   // that requires 16 byte alignment such as movdqa on x86.
   return 16;
 }
+
+
+#ifdef V8_TARGET_ARCH_ARM
+// 0xffff0fa0 is the hard coded address of a function provided by
+// the kernel which implements a memory barrier. On older
+// ARM architecture revisions (pre-v6) this may be implemented using
+// a syscall. This address is stable, and in active use (hard coded)
+// by at least glibc-2.7 and the Android C library.
+typedef void (*LinuxKernelMemoryBarrierFunc)(void);
+LinuxKernelMemoryBarrierFunc pLinuxKernelMemoryBarrier __attribute__((weak)) =
+    (LinuxKernelMemoryBarrierFunc) 0xffff0fa0;
+#endif
+
+void OS::ReleaseStore(volatile AtomicWord* ptr, AtomicWord value) {
+#ifdef V8_TARGET_ARCH_ARM
+  pLinuxKernelMemoryBarrier();
+#else
+  __asm__ __volatile__("" : : : "memory");
+  // An x86 store acts as a release barrier.
+#endif
+  *ptr = value;
+}


 const char* OS::LocalTimezone(double time) {
=======================================
--- /branches/bleeding_edge/src/platform-macos.cc       Wed May  5 05:44:06 2010
+++ /branches/bleeding_edge/src/platform-macos.cc       Fri May 21 22:27:19 2010
@@ -39,6 +39,7 @@
 #include <pthread.h>
 #include <semaphore.h>
 #include <signal.h>
+#include <libkern/OSAtomic.h>
 #include <mach/mach.h>
 #include <mach/semaphore.h>
 #include <mach/task.h>
@@ -257,6 +258,12 @@
   // Function Call Guide".
   return 16;
 }
+
+
+void OS::ReleaseStore(volatile AtomicWord* ptr, AtomicWord value) {
+  OSMemoryBarrier();
+  *ptr = value;
+}


 const char* OS::LocalTimezone(double time) {
=======================================
--- /branches/bleeding_edge/src/platform-win32.cc       Wed May  5 05:39:21 2010
+++ /branches/bleeding_edge/src/platform-win32.cc       Fri May 21 22:27:19 2010
@@ -1338,6 +1338,12 @@
   return 8;  // Floating-point math runs faster with 8-byte alignment.
 #endif
 }
+
+
+void OS::ReleaseStore(volatile AtomicWord* ptr, AtomicWord value) {
+  MemoryBarrier();
+  *ptr = value;
+}


 bool VirtualMemory::IsReserved() {
=======================================
--- /branches/bleeding_edge/src/platform.h      Wed May 19 00:36:25 2010
+++ /branches/bleeding_edge/src/platform.h      Fri May 21 22:27:19 2010
@@ -277,6 +277,8 @@
   // the platform doesn't care. Guaranteed to be a power of two.
   static int ActivationFrameAlignment();

+  static void ReleaseStore(volatile AtomicWord* ptr, AtomicWord value);
+
  private:
   static const int msPerSecond = 1000;

=======================================
--- /branches/bleeding_edge/src/v8.cc   Fri May 21 06:46:35 2010
+++ /branches/bleeding_edge/src/v8.cc   Fri May 21 22:27:19 2010
@@ -149,10 +149,10 @@

   Top::TearDown();

-  CpuProfiler::TearDown();
-
   Heap::TearDown();

+  CpuProfiler::TearDown();
+
   Logger::TearDown();

   is_running_ = false;
=======================================
--- /branches/bleeding_edge/test/cctest/SConscript      Wed May  5 06:51:27 2010
+++ /branches/bleeding_edge/test/cctest/SConscript      Fri May 21 22:27:19 2010
@@ -71,6 +71,7 @@
     'test-strings.cc',
     'test-threads.cc',
     'test-thread-termination.cc',
+    'test-unbound-queue.cc',
     'test-utils.cc',
     'test-version.cc'
   ],
=======================================
--- /branches/bleeding_edge/test/cctest/test-circular-queue.cc Mon Mar 22 07:23:45 2010 +++ /branches/bleeding_edge/test/cctest/test-circular-queue.cc Fri May 21 22:27:19 2010
@@ -1,6 +1,6 @@
 // Copyright 2010 the V8 project authors. All rights reserved.
 //
-// Tests of circular queues.
+// Tests of the circular queue.

 #include "v8.h"
 #include "circular-queue-inl.h"
@@ -8,53 +8,9 @@

 namespace i = v8::internal;

-using i::CircularQueue;
 using i::SamplingCircularQueue;


-TEST(SingleRecordCircularQueue) {
-  typedef int Record;
-  CircularQueue<Record> cq(sizeof(Record) * 2);
-  CHECK(cq.IsEmpty());
-  cq.Enqueue(1);
-  CHECK(!cq.IsEmpty());
-  Record rec = 0;
-  cq.Dequeue(&rec);
-  CHECK_EQ(1, rec);
-  CHECK(cq.IsEmpty());
-}
-
-
-TEST(MultipleRecordsCircularQueue) {
-  typedef int Record;
-  const int kQueueSize = 10;
-  CircularQueue<Record> cq(sizeof(Record) * (kQueueSize + 1));
-  CHECK(cq.IsEmpty());
-  cq.Enqueue(1);
-  CHECK(!cq.IsEmpty());
-  for (int i = 2; i <= 5; ++i) {
-    cq.Enqueue(i);
-    CHECK(!cq.IsEmpty());
-  }
-  Record rec = 0;
-  for (int i = 1; i <= 4; ++i) {
-    CHECK(!cq.IsEmpty());
-    cq.Dequeue(&rec);
-    CHECK_EQ(i, rec);
-  }
-  for (int i = 6; i <= 12; ++i) {
-    cq.Enqueue(i);
-    CHECK(!cq.IsEmpty());
-  }
-  for (int i = 5; i <= 12; ++i) {
-    CHECK(!cq.IsEmpty());
-    cq.Dequeue(&rec);
-    CHECK_EQ(i, rec);
-  }
-  CHECK(cq.IsEmpty());
-}
-
-
 TEST(SamplingCircularQueue) {
   typedef SamplingCircularQueue::Cell Record;
   const int kRecordsPerChunk = 4;
=======================================
--- /branches/bleeding_edge/tools/gyp/v8.gyp    Mon May 17 08:41:35 2010
+++ /branches/bleeding_edge/tools/gyp/v8.gyp    Fri May 21 22:27:19 2010
@@ -412,6 +412,8 @@
         '../../src/top.h',
         '../../src/type-info.cc',
         '../../src/type-info.h',
+        '../../src/unbound-queue-inl.h',
+        '../../src/unbound-queue.h',
         '../../src/unicode-inl.h',
         '../../src/unicode.cc',
         '../../src/unicode.h',
=======================================
--- /branches/bleeding_edge/tools/v8.xcodeproj/project.pbxproj Fri May 21 02:23:33 2010 +++ /branches/bleeding_edge/tools/v8.xcodeproj/project.pbxproj Fri May 21 22:27:19 2010
@@ -627,6 +627,8 @@
9FBE03E410BD412600F8BFBA /* fast-codegen-arm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "fast-codegen-arm.cc"; path = "arm/fast-codegen-arm.cc"; sourceTree = "<group>"; }; 9FC86ABB0F5FEDAC00F22668 /* oprofile-agent.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "oprofile-agent.cc"; sourceTree = "<group>"; }; 9FC86ABC0F5FEDAC00F22668 /* oprofile-agent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "oprofile-agent.h"; sourceTree = "<group>"; }; + 9FF7A28211A642EA0051B8F2 /* unbound-queue-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "unbound-queue-inl.h"; sourceTree = "<group>"; }; + 9FF7A28311A642EA0051B8F2 /* unbound-queue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "unbound-queue.h"; sourceTree = "<group>"; };
 /* End PBXFileReference section */

 /* Begin PBXFrameworksBuildPhase section */
@@ -970,6 +972,8 @@
                                897FF1910E719B8F00D62E90 /* top.h */,
                                9FA38BAE1175B2D200C4CD55 /* type-info.cc */,
                                9FA38BAF1175B2D200C4CD55 /* type-info.h */,
+                               9FF7A28211A642EA0051B8F2 /* unbound-queue-inl.h 
*/,
+                               9FF7A28311A642EA0051B8F2 /* unbound-queue.h */,
                                897FF1920E719B8F00D62E90 /* unicode-inl.h */,
                                897FF1930E719B8F00D62E90 /* unicode.cc */,
                                897FF1940E719B8F00D62E90 /* unicode.h */,
=======================================
--- /branches/bleeding_edge/tools/visual_studio/v8_base.vcproj Mon May 10 04:32:25 2010 +++ /branches/bleeding_edge/tools/visual_studio/v8_base.vcproj Fri May 21 22:27:19 2010
@@ -959,6 +959,14 @@
                        <File
                                RelativePath="..\..\src\type-info.h"
                                >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\unbound-queue-inl.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\unbound-queue.h"
+                               >
                        </File>
                        <File
                                RelativePath="..\..\src\unicode-inl.h"
=======================================
--- /branches/bleeding_edge/tools/visual_studio/v8_base_arm.vcproj Mon May 10 04:32:25 2010 +++ /branches/bleeding_edge/tools/visual_studio/v8_base_arm.vcproj Fri May 21 22:27:19 2010
@@ -951,6 +951,14 @@
                        <File
                                RelativePath="..\..\src\type-info.h"
                                >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\unbound-queue-inl.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\unbound-queue.h"
+                               >
                        </File>
                        <File
                                RelativePath="..\..\src\unicode-inl.h"
=======================================
--- /branches/bleeding_edge/tools/visual_studio/v8_base_x64.vcproj Mon May 10 04:32:25 2010 +++ /branches/bleeding_edge/tools/visual_studio/v8_base_x64.vcproj Fri May 21 22:27:19 2010
@@ -936,6 +936,14 @@
                        <File
                                RelativePath="..\..\src\type-info.h"
                                >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\unbound-queue-inl.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\unbound-queue.h"
+                               >
                        </File>
                        <File
                                RelativePath="..\..\src\unicode-inl.h"
=======================================
--- /branches/bleeding_edge/tools/visual_studio/v8_cctest.vcproj Fri Mar 19 06:51:01 2010 +++ /branches/bleeding_edge/tools/visual_studio/v8_cctest.vcproj Fri May 21 22:27:19 2010
@@ -246,6 +246,10 @@
                <File
                        RelativePath="..\..\test\cctest\test-strings.cc"
                        >
+               </File>
+               <File
+                       RelativePath="..\..\test\cctest\test-unbound-queue.cc"
+                       >
                </File>
                <File
                        RelativePath="..\..\test\cctest\test-utils.cc"

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

Reply via email to