Merge from Chromium at DEPS revision 261286

This commit was generated by merge_to_master.py.

Change-Id: I756d37445fd7f470b1689ad81318e715d4244987
diff --git a/Source/heap/Handle.h b/Source/heap/Handle.h
index 20c629c..4025e95 100644
--- a/Source/heap/Handle.h
+++ b/Source/heap/Handle.h
@@ -806,6 +806,18 @@
     static const bool canMoveWithMemcpy = true;
 };
 
+template <typename T> struct VectorTraits<WebCore::HeapVector<T, 0> > : VectorTraitsBase<WebCore::HeapVector<T, 0> > {
+    static const bool needsDestruction = false;
+    static const bool canInitializeWithMemset = true;
+    static const bool canMoveWithMemcpy = true;
+};
+
+template <typename T, size_t inlineCapacity> struct VectorTraits<WebCore::HeapVector<T, inlineCapacity> > : VectorTraitsBase<WebCore::HeapVector<T, inlineCapacity> > {
+    static const bool needsDestruction = VectorTraits<T>::needsDestruction;
+    static const bool canInitializeWithMemset = VectorTraits<T>::canInitializeWithMemset;
+    static const bool canMoveWithMemcpy = VectorTraits<T>::canMoveWithMemcpy;
+};
+
 template<typename T> struct HashTraits<WebCore::Member<T> > : SimpleClassHashTraits<WebCore::Member<T> > {
     static const bool needsDestruction = false;
     // FIXME: The distinction between PeekInType and PassInType is there for
@@ -891,9 +903,9 @@
     static const bool value = true;
 };
 
-template<typename Key, typename Value, typename Extractor, typename Traits, typename KeyTraits>
-struct IsWeak<WebCore::HeapHashTableBacking<Key, Value, Extractor, Traits, KeyTraits> > {
-    static const bool value = Traits::isWeak;
+template<typename Table>
+struct IsWeak<WebCore::HeapHashTableBacking<Table> > {
+    static const bool value = Table::ValueTraits::isWeak;
 };
 
 template<typename T> inline T* getPtr(const WebCore::Member<T>& p)
@@ -908,8 +920,8 @@
 
 // We define specialization of the NeedsTracing trait for off heap collections
 // since we don't support tracing them.
-template<typename T>
-struct NeedsTracing<Vector<T> > {
+template<typename T, size_t N>
+struct NeedsTracing<Vector<T, N> > {
     static const bool value = false;
 };
 
diff --git a/Source/heap/Heap.cpp b/Source/heap/Heap.cpp
index 88a6e8b..bfd702b 100644
--- a/Source/heap/Heap.cpp
+++ b/Source/heap/Heap.cpp
@@ -1305,6 +1305,8 @@
 
 void Heap::collectGarbage(ThreadState::StackState stackState, GCType gcType)
 {
+    if (gcType == ForcedForTesting && stackState != ThreadState::NoHeapPointersOnStack)
+        ThreadState::current()->setForcedForTesting(true);
     ThreadState::current()->clearGCRequested();
     GCScope gcScope(stackState);
 
diff --git a/Source/heap/Heap.h b/Source/heap/Heap.h
index c84a0ce..b00320f 100644
--- a/Source/heap/Heap.h
+++ b/Source/heap/Heap.h
@@ -1312,9 +1312,9 @@
 
     // Like the VectorBackingHelper, but this type is used for HashSet and
     // HashMap, both of which are implemented using HashTable.
-    template<typename T, typename U, typename V, typename W, typename X>
+    template<typename Table>
     struct HashTableBackingHelper {
-        typedef HeapHashTableBacking<T, U, V, W, X> Type;
+        typedef HeapHashTableBacking<Table> Type;
     };
 
     template<typename T>
@@ -1399,7 +1399,7 @@
 };
 
 template<typename Key, typename Value, typename T, typename U, typename V>
-struct ThreadingTrait<HashMap<Key, Value, HeapAllocator, T, U, V> > {
+struct ThreadingTrait<HashMap<Key, Value, T, U, V, HeapAllocator> > {
     static const ThreadAffinity Affinity =
         (ThreadingTrait<Key>::Affinity == MainThreadOnly)
         && (ThreadingTrait<Value>::Affinity == MainThreadOnly) ? MainThreadOnly : AnyThread;
@@ -1413,7 +1413,7 @@
 };
 
 template<typename T, typename U, typename V>
-struct ThreadingTrait<HashSet<T, HeapAllocator, U, V> > {
+struct ThreadingTrait<HashSet<T, U, V, HeapAllocator> > {
     static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity;
 };
 
@@ -1428,17 +1428,21 @@
     static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity;
 };
 
-template<typename Key, typename Value, typename Extractor, typename Traits, typename KeyTraits>
-struct ThreadingTrait<HeapHashTableBacking<Key, Value, Extractor, Traits, KeyTraits> > {
+template<typename Table>
+struct ThreadingTrait<HeapHashTableBacking<Table> > {
+    typedef typename Table::KeyType Key;
+    typedef typename Table::ValueType Value;
     static const ThreadAffinity Affinity =
         (ThreadingTrait<Key>::Affinity == MainThreadOnly)
         && (ThreadingTrait<Value>::Affinity == MainThreadOnly) ? MainThreadOnly : AnyThread;
 };
 
-template<typename Key, typename Value>
-struct ThreadingTrait<HeapHashMap<Key, Value> > : public ThreadingTrait<HashMap<Key, Value, HeapAllocator> > { };
-template<typename Value>
-struct ThreadingTrait<HeapHashSet<Value> > : public ThreadingTrait<HashSet<Value, HeapAllocator> > { };
+template<typename T, typename U, typename V, typename W, typename X>
+struct ThreadingTrait<HeapHashMap<T, U, V, W, X> > : public ThreadingTrait<HashMap<T, U, V, W, X, HeapAllocator> > { };
+
+template<typename T, typename U, typename V>
+struct ThreadingTrait<HeapHashSet<T, U, V> > : public ThreadingTrait<HashSet<T, U, V, HeapAllocator> > { };
+
 template<typename T, size_t inlineCapacity>
 struct ThreadingTrait<HeapVector<T, inlineCapacity> > : public ThreadingTrait<Vector<T, inlineCapacity, HeapAllocator> > { };
 
@@ -1516,17 +1520,17 @@
     Traits::needsDestruction,
 };
 
-template<typename T, typename U, typename V, typename W, typename X>
-struct GCInfoTrait<HeapHashTableBacking<T, U, V, W, X> > {
+template<typename Table>
+struct GCInfoTrait<HeapHashTableBacking<Table> > {
     static const GCInfo* get() { return &info; }
     static const GCInfo info;
 };
 
-template<typename T, typename U, typename V, typename Traits, typename W>
-const GCInfo GCInfoTrait<HeapHashTableBacking<T, U, V, Traits, W> >::info = {
-    TraceTrait<HeapHashTableBacking<T, U, V, Traits, W> >::trace,
-    FinalizerTrait<HeapHashTableBacking<T, U, V, Traits, W> >::finalize,
-    Traits::needsDestruction,
+template<typename Table>
+const GCInfo GCInfoTrait<HeapHashTableBacking<Table> >::info = {
+    TraceTrait<HeapHashTableBacking<Table> >::trace,
+    HeapHashTableBacking<Table>::finalize,
+    Table::ValueTraits::needsDestruction,
 };
 
 template<bool markWeakMembersStrongly, typename T, typename Traits>
@@ -1550,15 +1554,17 @@
     }
 };
 
-template<bool markWeakMembersStrongly, typename Key, typename Value, typename Extractor, typename Traits, typename KeyTraits>
+template<bool markWeakMembersStrongly, typename Table>
 struct BaseVisitHashTableBackingTrait {
+    typedef typename Table::ValueType Value;
+    typedef typename Table::ValueTraits Traits;
     static void mark(WebCore::Visitor* visitor, void* self)
     {
         Value* array = reinterpret_cast<Value*>(self);
         WebCore::FinalizedHeapObjectHeader* header = WebCore::FinalizedHeapObjectHeader::fromPayload(self);
         size_t length = header->payloadSize() / sizeof(Value);
         for (size_t i = 0; i < length; i++) {
-            if (!WTF::HashTableHelper<Value, Extractor, KeyTraits>::isEmptyOrDeletedBucket(array[i]))
+            if (!WTF::HashTableHelper<Value, typename Table::ExtractorType, typename Table::KeyTraitsType>::isEmptyOrDeletedBucket(array[i]))
                 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Traits::isWeak, markWeakMembersStrongly, Value, Traits>::mark(visitor, array[i]);
         }
     }
@@ -1605,13 +1611,13 @@
 };
 
 // FTT (hash table)
-template<typename Key, typename Value, typename Extractor, typename Traits, typename KeyTraits>
-struct CollectionBackingTraceTrait<false, true, true, HeapHashTableBacking<Key, Value, Extractor, Traits, KeyTraits>, void> : public BaseVisitHashTableBackingTrait<true, Key, Value, Extractor, Traits, KeyTraits> {
+template<typename Table>
+struct CollectionBackingTraceTrait<false, true, true, HeapHashTableBacking<Table>, void> : public BaseVisitHashTableBackingTrait<true, Table> {
 };
 
 // TXX (hash table)
-template<bool isWeak, bool markWeakMembersStrongly, typename Key, typename Value, typename Extractor, typename Traits, typename KeyTraits>
-struct CollectionBackingTraceTrait<true, isWeak, markWeakMembersStrongly, HeapHashTableBacking<Key, Value, Extractor, Traits, KeyTraits>, void> : public BaseVisitHashTableBackingTrait<markWeakMembersStrongly, Key, Value, Extractor, Traits, KeyTraits> {
+template<bool isWeak, bool markWeakMembersStrongly, typename Table>
+struct CollectionBackingTraceTrait<true, isWeak, markWeakMembersStrongly, HeapHashTableBacking<Table>, void> : public BaseVisitHashTableBackingTrait<markWeakMembersStrongly, Table> {
 };
 
 // FTT (key value pair)
@@ -1685,13 +1691,14 @@
 // we disable weak processing of table entries. When the backing is found
 // through the owning hash table we mark differently, in order to do weak
 // processing.
-template<typename Key, typename Value, typename Extractor, typename Traits, typename KeyTraits>
-struct TraceTrait<HeapHashTableBacking<Key, Value, Extractor, Traits, KeyTraits> > {
-    typedef HeapHashTableBacking<Key, Value, Extractor, Traits, KeyTraits> Backing;
+template<typename Table>
+struct TraceTrait<HeapHashTableBacking<Table> > {
+    typedef HeapHashTableBacking<Table> Backing;
+    typedef typename Table::ValueTraits Traits;
     static void trace(WebCore::Visitor* visitor, void* self)
     {
         if (WTF::ShouldBeTraced<Traits>::value || Traits::isWeak)
-            CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Traits::isWeak, true, HeapHashTableBacking<Key, Value, Extractor, Traits, KeyTraits>, void>::mark(visitor, self);
+            CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Traits::isWeak, true, Backing, void>::mark(visitor, self);
     }
     static void mark(Visitor* visitor, const Backing* backing)
     {
@@ -1708,6 +1715,22 @@
     }
 };
 
+template<typename Table>
+void HeapHashTableBacking<Table>::finalize(void* pointer)
+{
+    typedef typename Table::ValueType Value;
+    ASSERT(Table::ValueTraits::needsDestruction);
+    FinalizedHeapObjectHeader* header = FinalizedHeapObjectHeader::fromPayload(pointer);
+    // Use the payload size as recorded by the heap to determine how many
+    // elements to finalize.
+    size_t length = header->payloadSize() / sizeof(Value);
+    Value* table = reinterpret_cast<Value*>(pointer);
+    for (unsigned i = 0; i < length; i++) {
+        if (!Table::isEmptyOrDeletedBucket(table[i]))
+            table[i].~Value();
+    }
+}
+
 template<typename T, typename U, typename V, typename W, typename X>
 struct GCInfoTrait<HeapHashMap<T, U, V, W, X> > : public GCInfoTrait<HashMap<T, U, V, W, X, HeapAllocator> > { };
 template<typename T, typename U, typename V>
diff --git a/Source/heap/HeapTest.cpp b/Source/heap/HeapTest.cpp
index 005556e..f1bbe10 100644
--- a/Source/heap/HeapTest.cpp
+++ b/Source/heap/HeapTest.cpp
@@ -175,6 +175,13 @@
     static SimpleObject* create() { return new SimpleObject(); }
     void trace(Visitor*) { }
     char getPayload(int i) { return payload[i]; }
+    // This virtual method is unused but it is here to make sure
+    // that this object has a vtable. This object is used
+    // as the super class for objects that also have garbage
+    // collected mixins and having a virtual here makes sure
+    // that adjustment is needed both for marking and for isAlive
+    // checks.
+    virtual void virtualMethod() { }
 protected:
     SimpleObject() { }
     char payload[64];
@@ -708,6 +715,11 @@
         ++s_destructorCalls;
     }
 
+    // These are here with their default implementations so you can break in
+    // them in the debugger.
+    void ref() { RefCountedGarbageCollected<RefCountedAndGarbageCollected>::ref(); }
+    void deref() { RefCountedGarbageCollected<RefCountedAndGarbageCollected>::deref(); }
+
     void trace(Visitor*) { }
 
     static int s_destructorCalls;
@@ -1132,10 +1144,9 @@
 public:
     virtual void trace(Visitor* visitor) { }
 
-    char getPayload(int i) { return m_padding[i]; }
+    virtual char getPayload(int i) { return m_padding[i]; }
 
 protected:
-    // This is to force ptr diff for SimpleObject, Mixin, and UseMixin.
     int m_padding[8];
 };
 
@@ -2220,7 +2231,8 @@
 
 TEST(HeapTest, HeapWeakCollectionSimple)
 {
-
+    HeapStats initialHeapStats;
+    clearOutOldGarbage(&initialHeapStats);
     IntWrapper::s_destructorCalls = 0;
 
     PersistentHeapVector<Member<IntWrapper> > keepNumbersAlive;
@@ -2265,6 +2277,133 @@
     EXPECT_EQ(2u, weakSet->size());
 }
 
+class ThingWithDestructor {
+public:
+    ThingWithDestructor()
+        : m_x(emptyValue)
+    {
+        s_liveThingsWithDestructor++;
+    }
+
+    ThingWithDestructor(int x)
+        : m_x(x)
+    {
+        s_liveThingsWithDestructor++;
+    }
+
+    ThingWithDestructor(const ThingWithDestructor&other)
+    {
+        *this = other;
+        s_liveThingsWithDestructor++;
+    }
+
+    ~ThingWithDestructor()
+    {
+        s_liveThingsWithDestructor--;
+    }
+
+    int value() { return m_x; }
+
+    static int s_liveThingsWithDestructor;
+
+    unsigned hash() { return IntHash<int>::hash(m_x); }
+
+private:
+    static const int emptyValue = 0;
+    int m_x;
+};
+
+int ThingWithDestructor::s_liveThingsWithDestructor;
+
+struct ThingWithDestructorTraits : public HashTraits<ThingWithDestructor> {
+    static const bool needsDestruction = true;
+};
+
+static void heapMapDestructorHelper(bool clearMaps)
+{
+    HeapStats initialHeapStats;
+    clearOutOldGarbage(&initialHeapStats);
+    ThingWithDestructor::s_liveThingsWithDestructor = 0;
+
+    typedef HeapHashMap<WeakMember<IntWrapper>, RefPtr<RefCountedAndGarbageCollected> > RefMap;
+
+    typedef HeapHashMap<
+        WeakMember<IntWrapper>,
+        ThingWithDestructor,
+        DefaultHash<WeakMember<IntWrapper> >::Hash,
+        HashTraits<WeakMember<IntWrapper> >,
+        ThingWithDestructorTraits> Map;
+
+    Persistent<Map> map(new Map());
+    Persistent<RefMap> refMap(new RefMap());
+
+    Persistent<IntWrapper> luck(IntWrapper::create(103));
+
+    int baseLine, refBaseLine;
+
+    {
+        Map stackMap;
+        RefMap stackRefMap;
+
+        Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
+        Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
+
+        stackMap.add(IntWrapper::create(42), ThingWithDestructor(1729));
+        stackMap.add(luck, ThingWithDestructor(8128));
+        stackRefMap.add(IntWrapper::create(42), RefCountedAndGarbageCollected::create());
+        stackRefMap.add(luck, RefCountedAndGarbageCollected::create());
+
+        baseLine = ThingWithDestructor::s_liveThingsWithDestructor;
+        refBaseLine = RefCountedAndGarbageCollected::s_destructorCalls;
+
+        // Although the heap maps are on-stack, we can't expect prompt
+        // finalization of the elements, so when they go out of scope here we
+        // will not necessarily have called the relevant destructors.
+    }
+
+    // The RefCountedAndGarbageCollected things need an extra GC to discover
+    // that they are no longer ref counted.
+    Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
+    Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
+    EXPECT_EQ(baseLine - 2, ThingWithDestructor::s_liveThingsWithDestructor);
+    EXPECT_EQ(refBaseLine + 2, RefCountedAndGarbageCollected::s_destructorCalls);
+
+    // Now use maps kept alive with persistents. Here we don't expect any
+    // destructors to be called before there have been GCs.
+
+    map->add(IntWrapper::create(42), ThingWithDestructor(1729));
+    map->add(luck, ThingWithDestructor(8128));
+    refMap->add(IntWrapper::create(42), RefCountedAndGarbageCollected::create());
+    refMap->add(luck, RefCountedAndGarbageCollected::create());
+
+    baseLine  =  ThingWithDestructor::s_liveThingsWithDestructor;
+    refBaseLine = RefCountedAndGarbageCollected::s_destructorCalls;
+
+    luck.clear();
+    if (clearMaps) {
+        map->clear(); // Clear map.
+        refMap->clear(); // Clear map.
+    } else {
+        map.clear(); // Clear Persistent handle, not map.
+        refMap.clear(); // Clear Persistent handle, not map.
+        Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
+        Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
+    }
+
+    EXPECT_EQ(baseLine - 2, ThingWithDestructor::s_liveThingsWithDestructor);
+
+    // Need a GC to make sure that the RefCountedAndGarbageCollected thing
+    // noticies it's been decremented to zero.
+    Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
+    EXPECT_EQ(refBaseLine + 2, RefCountedAndGarbageCollected::s_destructorCalls);
+}
+
+TEST(HeapTest, HeapMapDestructor)
+{
+    heapMapDestructorHelper(true);
+    heapMapDestructorHelper(false);
+}
+
 typedef HeapHashSet<PairWeakStrong> WeakStrongSet;
 typedef HeapHashSet<PairWeakUnwrapped> WeakUnwrappedSet;
 typedef HeapHashSet<PairStrongWeak> StrongWeakSet;
@@ -2844,22 +2983,31 @@
     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
     EXPECT_EQ(1u, map->get(key).size());
     EXPECT_EQ(0, IntWrapper::s_destructorCalls);
+
+    keepAlive = nullptr;
+    Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
+    EXPECT_EQ(1, IntWrapper::s_destructorCalls);
 }
 
-TEST(heap, GarbageCollectedMixin)
+TEST(HeapTest, GarbageCollectedMixin)
 {
     HeapStats initialHeapStats;
     clearOutOldGarbage(&initialHeapStats);
 
     Persistent<UseMixin> usemixin = UseMixin::create();
-    ASSERT_EQ(0, UseMixin::s_traceCount);
+    EXPECT_EQ(0, UseMixin::s_traceCount);
     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
-    ASSERT_EQ(1, UseMixin::s_traceCount);
+    EXPECT_EQ(1, UseMixin::s_traceCount);
 
     Persistent<Mixin> mixin = usemixin;
     usemixin = nullptr;
     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
-    ASSERT_EQ(2, UseMixin::s_traceCount);
+    EXPECT_EQ(2, UseMixin::s_traceCount);
+
+    PersistentHeapHashSet<WeakMember<Mixin> > weakMap;
+    weakMap.add(UseMixin::create());
+    Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
+    EXPECT_EQ(0u, weakMap.size());
 }
 
 TEST(HeapTest, CollectionNesting2)
@@ -3062,4 +3210,27 @@
     EXPECT_EQ(512, OneKiloByteObject::s_destructorCalls);
 }
 
+class SimpleClassWithDestructor {
+public:
+    SimpleClassWithDestructor() { }
+    ~SimpleClassWithDestructor()
+    {
+        ASSERT(!s_wasDestructed);
+        s_wasDestructed = true;
+    }
+    static bool s_wasDestructed;
+};
+
+bool SimpleClassWithDestructor::s_wasDestructed;
+
+TEST(HeapTest, DestructorsCalledOnMapClear)
+{
+    HeapHashMap<SimpleClassWithDestructor*, OwnPtr<SimpleClassWithDestructor> > map;
+    SimpleClassWithDestructor* hasDestructor = new SimpleClassWithDestructor();
+    map.add(hasDestructor, adoptPtr(hasDestructor));
+    SimpleClassWithDestructor::s_wasDestructed = false;
+    map.clear();
+    ASSERT(SimpleClassWithDestructor::s_wasDestructed);
+}
+
 } // WebCore namespace
diff --git a/Source/heap/ThreadState.cpp b/Source/heap/ThreadState.cpp
index fa88655..f762436 100644
--- a/Source/heap/ThreadState.cpp
+++ b/Source/heap/ThreadState.cpp
@@ -181,6 +181,7 @@
     void doEnterSafePoint(ThreadState* state, intptr_t* stackEnd)
     {
         state->recordStackEnd(stackEnd);
+        state->copyStackUntilSafePointScope();
         // m_unparkedThreadCount tracks amount of unparked threads. It is
         // positive if and only if we have requested other threads to park
         // at safe-points in preparation for GC. The last thread to park
@@ -193,7 +194,6 @@
             MutexLocker locker(m_mutex);
             m_parked.signal(); // Safe point reached.
         }
-        state->copyStackUntilSafePointScope();
     }
 
     void enterSafePoint(ThreadState* state)
@@ -235,6 +235,7 @@
     , m_atSafePoint(false)
     , m_interruptors()
     , m_gcRequested(false)
+    , m_forcePreciseGCForTesting(false)
     , m_sweepRequested(0)
     , m_sweepInProgress(false)
     , m_noAllocationCount(0)
@@ -497,6 +498,26 @@
     m_gcRequested = false;
 }
 
+void ThreadState::performPendingGC(StackState stackState)
+{
+    if (stackState == NoHeapPointersOnStack && (gcRequested() || forcePreciseGCForTesting())) {
+        setForcedForTesting(false);
+        Heap::collectGarbage(NoHeapPointersOnStack);
+    }
+}
+
+void ThreadState::setForcedForTesting(bool value)
+{
+    checkThread();
+    m_forcePreciseGCForTesting = value;
+}
+
+bool ThreadState::forcePreciseGCForTesting()
+{
+    checkThread();
+    return m_forcePreciseGCForTesting;
+}
+
 bool ThreadState::isConsistentForGC()
 {
     for (int i = 0; i < NumberOfHeaps; i++) {
@@ -589,8 +610,7 @@
 void ThreadState::safePoint(StackState stackState)
 {
     checkThread();
-    if (stackState == NoHeapPointersOnStack && gcRequested())
-        Heap::collectGarbage(NoHeapPointersOnStack);
+    performPendingGC(stackState);
     m_stackState = stackState;
     s_safePointBarrier->checkAndPark(this);
     m_stackState = HeapPointersOnStack;
@@ -628,8 +648,7 @@
         scopeMarker = adjustScopeMarkerForAdressSanitizer(scopeMarker);
 #endif
     ASSERT(stackState == NoHeapPointersOnStack || scopeMarker);
-    if (stackState == NoHeapPointersOnStack && gcRequested())
-        Heap::collectGarbage(NoHeapPointersOnStack);
+    performPendingGC(stackState);
     checkThread();
     ASSERT(!m_atSafePoint);
     m_atSafePoint = true;
diff --git a/Source/heap/ThreadState.h b/Source/heap/ThreadState.h
index 3e79915..776dccb 100644
--- a/Source/heap/ThreadState.h
+++ b/Source/heap/ThreadState.h
@@ -278,6 +278,15 @@
     void setGCRequested();
     void clearGCRequested();
 
+    // Was the last GC forced for testing? This is set when garbage collection
+    // is forced for testing and there are pointers on the stack. It remains
+    // set until a garbage collection is triggered with no pointers on the stack.
+    // This is used for layout tests that trigger GCs and check if objects are
+    // dead at a given point in time. That only reliably works when we get
+    // precise GCs with no conservative stack scanning.
+    void setForcedForTesting(bool);
+    bool forcePreciseGCForTesting();
+
     bool sweepRequested();
     void setSweepRequested();
     void clearSweepRequested();
@@ -497,6 +506,8 @@
         m_safePointScopeMarker = 0;
     }
 
+    void performPendingGC(StackState);
+
     // Finds the Blink HeapPage in this thread-specific heap
     // corresponding to a given address. Return 0 if the address is
     // not contained in any of the pages. This does not consider
@@ -540,6 +551,7 @@
     bool m_atSafePoint;
     Vector<Interruptor*> m_interruptors;
     bool m_gcRequested;
+    bool m_forcePreciseGCForTesting;
     volatile int m_sweepRequested;
     bool m_sweepInProgress;
     size_t m_noAllocationCount;
diff --git a/Source/heap/Visitor.h b/Source/heap/Visitor.h
index 75a97a3..4d52a03 100644
--- a/Source/heap/Visitor.h
+++ b/Source/heap/Visitor.h
@@ -179,12 +179,7 @@
 
 template<typename T>
 struct ObjectAliveTrait {
-    static bool isAlive(Visitor*, T);
-};
-
-template<typename T>
-struct ObjectAliveTrait<Member<T> > {
-    static bool isAlive(Visitor*, const Member<T>&);
+    static bool isAlive(Visitor*, T*);
 };
 
 // Visitor is used to traverse the Blink object graph. Used for the
@@ -366,7 +361,10 @@
 
     virtual bool isMarked(const void*) = 0;
 
-    template<typename T> inline bool isAlive(T obj) { return ObjectAliveTrait<T>::isAlive(this, obj); }
+    template<typename T> inline bool isAlive(T* obj)
+    {
+        return ObjectAliveTrait<T>::isAlive(this, obj);
+    }
     template<typename T> inline bool isAlive(const Member<T>& member)
     {
         return isAlive(member.get());
@@ -480,8 +478,12 @@
 
 template<typename T, typename Traits = WTF::VectorTraits<T> >
 class HeapVectorBacking;
-template<typename Key, typename Value, typename Extractor, typename Traits, typename KeyTraits>
-class HeapHashTableBacking;
+
+template<typename Table>
+class HeapHashTableBacking {
+public:
+    static void finalize(void* pointer);
+};
 
 template<typename T>
 class DefaultTraceTrait<T, false> {
@@ -521,7 +523,7 @@
 template<typename T>
 class DefaultObjectAliveTrait<T, false> {
 public:
-    static bool isAlive(Visitor* visitor, T obj)
+    static bool isAlive(Visitor* visitor, T* obj)
     {
         return visitor->isMarked(obj);
     }
@@ -530,20 +532,16 @@
 template<typename T>
 class DefaultObjectAliveTrait<T, true> {
 public:
-    static bool isAlive(Visitor* visitor, T obj)
+    static bool isAlive(Visitor* visitor, T* obj)
     {
         return obj->isAlive(visitor);
     }
 };
 
-template<typename T> bool ObjectAliveTrait<T>::isAlive(Visitor* visitor, T obj)
+template<typename T> bool ObjectAliveTrait<T>::isAlive(Visitor* visitor, T* obj)
 {
     return DefaultObjectAliveTrait<T>::isAlive(visitor, obj);
 }
-template<typename T> bool ObjectAliveTrait<Member<T> >::isAlive(Visitor* visitor, const Member<T>& obj)
-{
-    return visitor->isMarked(obj.get());
-}
 
 // The GarbageCollectedMixin interface and helper macro
 // USING_GARBAGE_COLLECTED_MIXIN can be used to automatically define
diff --git a/Source/heap/asm/SaveRegisters_arm.S b/Source/heap/asm/SaveRegisters_arm.S
index 0d1251c..4e2f991 100644
--- a/Source/heap/asm/SaveRegisters_arm.S
+++ b/Source/heap/asm/SaveRegisters_arm.S
@@ -43,6 +43,7 @@
  * the THUMB/ARM interworking that appear in the component build.
  * When these issues are resolved this stub can be removed.
  */
+.align 2
 .code 16
 .thumb_func
 pushAllRegisters:
@@ -51,10 +52,13 @@
 
 .type pushAllRegistersARM, %function
 .hidden pushAllRegistersARM
+.align 4
 .code 32
 pushAllRegistersARM:
 #else
 /* ARM Mode */
+.align 4
+.code 32
 pushAllRegisters:
 #endif
         /* Push all callee-saved registers and save return address. */
diff --git a/Source/heap/blink_heap.target.darwin-arm.mk b/Source/heap/blink_heap.target.darwin-arm.mk
index e87bb61..5107b7b 100644
--- a/Source/heap/blink_heap.target.darwin-arm.mk
+++ b/Source/heap/blink_heap.target.darwin-arm.mk
@@ -71,6 +71,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
@@ -171,6 +172,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
diff --git a/Source/heap/blink_heap.target.darwin-mips.mk b/Source/heap/blink_heap.target.darwin-mips.mk
index 8006e73..b23adc6 100644
--- a/Source/heap/blink_heap.target.darwin-mips.mk
+++ b/Source/heap/blink_heap.target.darwin-mips.mk
@@ -70,6 +70,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
@@ -169,6 +170,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
diff --git a/Source/heap/blink_heap.target.darwin-x86.mk b/Source/heap/blink_heap.target.darwin-x86.mk
index 7a94f97..6142ae5 100644
--- a/Source/heap/blink_heap.target.darwin-x86.mk
+++ b/Source/heap/blink_heap.target.darwin-x86.mk
@@ -72,6 +72,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
@@ -172,6 +173,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
diff --git a/Source/heap/blink_heap.target.darwin-x86_64.mk b/Source/heap/blink_heap.target.darwin-x86_64.mk
index d0893ed..faf6599 100644
--- a/Source/heap/blink_heap.target.darwin-x86_64.mk
+++ b/Source/heap/blink_heap.target.darwin-x86_64.mk
@@ -72,6 +72,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
@@ -172,6 +173,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
diff --git a/Source/heap/blink_heap.target.linux-arm.mk b/Source/heap/blink_heap.target.linux-arm.mk
index e87bb61..5107b7b 100644
--- a/Source/heap/blink_heap.target.linux-arm.mk
+++ b/Source/heap/blink_heap.target.linux-arm.mk
@@ -71,6 +71,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
@@ -171,6 +172,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
diff --git a/Source/heap/blink_heap.target.linux-mips.mk b/Source/heap/blink_heap.target.linux-mips.mk
index 8006e73..b23adc6 100644
--- a/Source/heap/blink_heap.target.linux-mips.mk
+++ b/Source/heap/blink_heap.target.linux-mips.mk
@@ -70,6 +70,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
@@ -169,6 +170,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
diff --git a/Source/heap/blink_heap.target.linux-x86.mk b/Source/heap/blink_heap.target.linux-x86.mk
index 7a94f97..6142ae5 100644
--- a/Source/heap/blink_heap.target.linux-x86.mk
+++ b/Source/heap/blink_heap.target.linux-x86.mk
@@ -72,6 +72,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
@@ -172,6 +173,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
diff --git a/Source/heap/blink_heap.target.linux-x86_64.mk b/Source/heap/blink_heap.target.linux-x86_64.mk
index d0893ed..faf6599 100644
--- a/Source/heap/blink_heap.target.linux-x86_64.mk
+++ b/Source/heap/blink_heap.target.linux-x86_64.mk
@@ -72,6 +72,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
@@ -172,6 +173,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
diff --git a/Source/heap/blink_heap_asm_stubs.target.darwin-arm.mk b/Source/heap/blink_heap_asm_stubs.target.darwin-arm.mk
index 076968a..4c5b085 100644
--- a/Source/heap/blink_heap_asm_stubs.target.darwin-arm.mk
+++ b/Source/heap/blink_heap_asm_stubs.target.darwin-arm.mk
@@ -71,6 +71,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
@@ -156,6 +157,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
diff --git a/Source/heap/blink_heap_asm_stubs.target.darwin-mips.mk b/Source/heap/blink_heap_asm_stubs.target.darwin-mips.mk
index 8efaaa8..8420c77 100644
--- a/Source/heap/blink_heap_asm_stubs.target.darwin-mips.mk
+++ b/Source/heap/blink_heap_asm_stubs.target.darwin-mips.mk
@@ -71,6 +71,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
@@ -156,6 +157,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
diff --git a/Source/heap/blink_heap_asm_stubs.target.darwin-x86.mk b/Source/heap/blink_heap_asm_stubs.target.darwin-x86.mk
index 86840e9..0966d1f 100644
--- a/Source/heap/blink_heap_asm_stubs.target.darwin-x86.mk
+++ b/Source/heap/blink_heap_asm_stubs.target.darwin-x86.mk
@@ -90,6 +90,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
@@ -175,6 +176,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
diff --git a/Source/heap/blink_heap_asm_stubs.target.darwin-x86_64.mk b/Source/heap/blink_heap_asm_stubs.target.darwin-x86_64.mk
index 4d61b77..a91f543 100644
--- a/Source/heap/blink_heap_asm_stubs.target.darwin-x86_64.mk
+++ b/Source/heap/blink_heap_asm_stubs.target.darwin-x86_64.mk
@@ -90,6 +90,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
@@ -175,6 +176,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
diff --git a/Source/heap/blink_heap_asm_stubs.target.linux-arm.mk b/Source/heap/blink_heap_asm_stubs.target.linux-arm.mk
index 076968a..4c5b085 100644
--- a/Source/heap/blink_heap_asm_stubs.target.linux-arm.mk
+++ b/Source/heap/blink_heap_asm_stubs.target.linux-arm.mk
@@ -71,6 +71,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
@@ -156,6 +157,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
diff --git a/Source/heap/blink_heap_asm_stubs.target.linux-mips.mk b/Source/heap/blink_heap_asm_stubs.target.linux-mips.mk
index 8efaaa8..8420c77 100644
--- a/Source/heap/blink_heap_asm_stubs.target.linux-mips.mk
+++ b/Source/heap/blink_heap_asm_stubs.target.linux-mips.mk
@@ -71,6 +71,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
@@ -156,6 +157,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
diff --git a/Source/heap/blink_heap_asm_stubs.target.linux-x86.mk b/Source/heap/blink_heap_asm_stubs.target.linux-x86.mk
index 86840e9..0966d1f 100644
--- a/Source/heap/blink_heap_asm_stubs.target.linux-x86.mk
+++ b/Source/heap/blink_heap_asm_stubs.target.linux-x86.mk
@@ -90,6 +90,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
@@ -175,6 +176,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
diff --git a/Source/heap/blink_heap_asm_stubs.target.linux-x86_64.mk b/Source/heap/blink_heap_asm_stubs.target.linux-x86_64.mk
index 4d61b77..a91f543 100644
--- a/Source/heap/blink_heap_asm_stubs.target.linux-x86_64.mk
+++ b/Source/heap/blink_heap_asm_stubs.target.linux-x86_64.mk
@@ -90,6 +90,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
@@ -175,6 +176,7 @@
 	'-DDISABLE_NACL' \
 	'-DCHROMIUM_BUILD' \
 	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \