diff --git a/BUILD.gn b/BUILD.gn index 5f9f3a9..044f7c6 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -205,6 +205,7 @@ } else { deps += [ "//ios/net:ios_net_unittests", + "//ios/public/provider/web", "//ios/testing:ocmock_support_unittest", "//ios/web:ios_web_unittests", ]
diff --git a/DEPS b/DEPS index 6c08c19..8d273a6 100644 --- a/DEPS +++ b/DEPS
@@ -39,11 +39,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'c94cd7cc01b655b7f4289537962c36a4ee8dd63e', + 'skia_revision': '1d5127327111e00d0e4530adae73b11ad2ee3f42', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '00820330372dd1588a7f96649ad83fe5ffb9bbbf', + 'v8_revision': 'fd63469ff634889fcb372187901fd0176f02f1ad', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other.
diff --git a/base/trace_event/BUILD.gn b/base/trace_event/BUILD.gn index 70ebeaa..9b1aa0c 100644 --- a/base/trace_event/BUILD.gn +++ b/base/trace_event/BUILD.gn
@@ -5,6 +5,18 @@ source_set("trace_event") { sources = [ "common/trace_event_common.h", + "heap_profiler_allocation_context.cc", + "heap_profiler_allocation_context.h", + "heap_profiler_allocation_context_tracker.cc", + "heap_profiler_allocation_context_tracker.h", + "heap_profiler_allocation_register.cc", + "heap_profiler_allocation_register.h", + "heap_profiler_allocation_register_posix.cc", + "heap_profiler_allocation_register_win.cc", + "heap_profiler_heap_dump_writer.cc", + "heap_profiler_heap_dump_writer.h", + "heap_profiler_stack_frame_deduplicator.cc", + "heap_profiler_stack_frame_deduplicator.h", "java_heap_dump_provider_android.cc", "java_heap_dump_provider_android.h", "memory_allocator_dump.cc", @@ -18,14 +30,6 @@ "memory_dump_request_args.h", "memory_dump_session_state.cc", "memory_dump_session_state.h", - "memory_profiler_allocation_context.cc", - "memory_profiler_allocation_context.h", - "memory_profiler_allocation_register.cc", - "memory_profiler_allocation_register.h", - "memory_profiler_allocation_register_posix.cc", - "memory_profiler_allocation_register_win.cc", - "memory_profiler_heap_dump_writer.cc", - "memory_profiler_heap_dump_writer.h", "process_memory_dump.cc", "process_memory_dump.h", "process_memory_maps.cc", @@ -108,11 +112,12 @@ source_set("trace_event_unittests") { testonly = true sources = [ + "heap_profiler_allocation_context_tracker_unittest.cc", + "heap_profiler_allocation_register_unittest.cc", + "heap_profiler_stack_frame_deduplicator_unittest.cc", "java_heap_dump_provider_android_unittest.cc", "memory_allocator_dump_unittest.cc", "memory_dump_manager_unittest.cc", - "memory_profiler_allocation_context_unittest.cc", - "memory_profiler_allocation_register_unittest.cc", "process_memory_dump_unittest.cc", "process_memory_totals_dump_provider_unittest.cc", "trace_config_memory_test_util.h",
diff --git a/base/trace_event/heap_profiler_allocation_context.cc b/base/trace_event/heap_profiler_allocation_context.cc new file mode 100644 index 0000000..657f00c --- /dev/null +++ b/base/trace_event/heap_profiler_allocation_context.cc
@@ -0,0 +1,46 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/trace_event/heap_profiler_allocation_context.h" + +#include <cstring> + +#include "base/hash.h" + +namespace base { +namespace trace_event { + +bool operator==(const Backtrace& lhs, const Backtrace& rhs) { + // Pointer equality of the stack frames is assumed, so instead of doing a deep + // string comparison on all of the frames, a |memcmp| suffices. + return std::memcmp(lhs.frames, rhs.frames, sizeof(lhs.frames)) == 0; +} + +bool operator==(const AllocationContext& lhs, const AllocationContext& rhs) { + return (lhs.backtrace == rhs.backtrace) && (lhs.type_id == rhs.type_id); +} + +} // namespace trace_event +} // namespace base + +namespace BASE_HASH_NAMESPACE { +using base::trace_event::AllocationContext; +using base::trace_event::Backtrace; + +size_t hash<Backtrace>::operator()(const Backtrace& backtrace) const { + return base::SuperFastHash(reinterpret_cast<const char*>(backtrace.frames), + sizeof(backtrace.frames)); +} + +size_t hash<AllocationContext>::operator()(const AllocationContext& ctx) const { + size_t ctx_hash = hash<Backtrace>()(ctx.backtrace); + + // Multiply one side to break the commutativity of +. Multiplication with a + // number coprime to |numeric_limits<size_t>::max() + 1| is bijective so + // randomness is preserved. The type ID is assumed to be distributed randomly + // already so there is no need to hash it. + return (ctx_hash * 3) + static_cast<size_t>(ctx.type_id); +} + +} // BASE_HASH_NAMESPACE
diff --git a/base/trace_event/heap_profiler_allocation_context.h b/base/trace_event/heap_profiler_allocation_context.h new file mode 100644 index 0000000..070daf1 --- /dev/null +++ b/base/trace_event/heap_profiler_allocation_context.h
@@ -0,0 +1,87 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_TRACE_EVENT_HEAP_PROFILER_ALLOCATION_CONTEXT_H_ +#define BASE_TRACE_EVENT_HEAP_PROFILER_ALLOCATION_CONTEXT_H_ + +#include <stdint.h> + +#include "base/base_export.h" +#include "base/containers/hash_tables.h" + +namespace base { +namespace trace_event { + +// When heap profiling is enabled, tracing keeps track of the allocation +// context for each allocation intercepted. It is generated by the +// |AllocationContextTracker| which keeps stacks of context in TLS. +// The tracker is initialized lazily. + +// The backtrace in the allocation context is a snapshot of the stack. For now, +// this is the pseudo stack where frames are created by trace event macros. In +// the future, we might add the option to use the native call stack. In that +// case, |Backtrace| and |AllocationContextTracker::GetContextSnapshot| might +// have different implementations that can be selected by a compile time flag. + +// The number of stack frames stored in the backtrace is a trade off between +// memory used for tracing and accuracy. Measurements done on a prototype +// revealed that: +// +// - In 60 percent of the cases, stack depth <= 7. +// - In 87 percent of the cases, stack depth <= 9. +// - In 95 percent of the cases, stack depth <= 11. +// +// See the design doc (https://goo.gl/4s7v7b) for more details. + +using StackFrame = const char*; + +struct BASE_EXPORT Backtrace { + // Unused backtrace frames are filled with nullptr frames. If the stack is + // higher than what can be stored here, the bottom frames are stored. Based + // on the data above, a depth of 12 captures the full stack in the vast + // majority of the cases. + StackFrame frames[12]; +}; + +bool BASE_EXPORT operator==(const Backtrace& lhs, const Backtrace& rhs); + +// The |AllocationContext| is context metadata that is kept for every allocation +// when heap profiling is enabled. To simplify memory management for book- +// keeping, this struct has a fixed size. All |const char*|s here must have +// static lifetime. +// TODO(ruuda): Make the default constructor private to avoid accidentally +// constructing an instance and forgetting to initialize it. Only +// |AllocationContextTracker| should be able to construct. (And tests.) +struct BASE_EXPORT AllocationContext { + // A type ID is a number that is unique for every C++ type. A type ID is + // stored instead of the type name to avoid inflating the binary with type + // name strings. There is an out of band lookup table mapping IDs to the type + // names. A value of 0 means that the type is not known. + using TypeId = uint16_t; + + Backtrace backtrace; + TypeId type_id; +}; + +bool BASE_EXPORT operator==(const AllocationContext& lhs, + const AllocationContext& rhs); + +} // namespace trace_event +} // namespace base + +namespace BASE_HASH_NAMESPACE { + +template <> +struct hash<base::trace_event::Backtrace> { + size_t operator()(const base::trace_event::Backtrace& backtrace) const; +}; + +template <> +struct hash<base::trace_event::AllocationContext> { + size_t operator()(const base::trace_event::AllocationContext& context) const; +}; + +} // BASE_HASH_NAMESPACE + +#endif // BASE_TRACE_EVENT_HEAP_PROFILER_ALLOCATION_CONTEXT_H_
diff --git a/base/trace_event/heap_profiler_allocation_context_tracker.cc b/base/trace_event/heap_profiler_allocation_context_tracker.cc new file mode 100644 index 0000000..b58fb60 --- /dev/null +++ b/base/trace_event/heap_profiler_allocation_context_tracker.cc
@@ -0,0 +1,121 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/trace_event/heap_profiler_allocation_context_tracker.h" + +#include <algorithm> + +#include "base/atomicops.h" +#include "base/threading/thread_local_storage.h" +#include "base/trace_event/heap_profiler_allocation_context.h" + +namespace base { +namespace trace_event { + +subtle::Atomic32 AllocationContextTracker::capture_enabled_ = 0; + +namespace { + +ThreadLocalStorage::StaticSlot g_tls_alloc_ctx_tracker = TLS_INITIALIZER; + +// This function is added to the TLS slot to clean up the instance when the +// thread exits. +void DestructAllocationContextTracker(void* alloc_ctx_tracker) { + delete static_cast<AllocationContextTracker*>(alloc_ctx_tracker); +} + +// Returns a pointer past the end of the fixed-size array |array| of |T| of +// length |N|, identical to C++11 |std::end|. +template <typename T, int N> +T* End(T(&array)[N]) { + return array + N; +} + +} // namespace + +AllocationContextTracker::AllocationContextTracker() {} +AllocationContextTracker::~AllocationContextTracker() {} + +// static +AllocationContextTracker* AllocationContextTracker::GetThreadLocalTracker() { + auto tracker = + static_cast<AllocationContextTracker*>(g_tls_alloc_ctx_tracker.Get()); + + if (!tracker) { + tracker = new AllocationContextTracker(); + g_tls_alloc_ctx_tracker.Set(tracker); + } + + return tracker; +} + +// static +void AllocationContextTracker::SetCaptureEnabled(bool enabled) { + // When enabling capturing, also initialize the TLS slot. This does not create + // a TLS instance yet. + if (enabled && !g_tls_alloc_ctx_tracker.initialized()) + g_tls_alloc_ctx_tracker.Initialize(DestructAllocationContextTracker); + + // Release ordering ensures that when a thread observes |capture_enabled_| to + // be true through an acquire load, the TLS slot has been initialized. + subtle::Release_Store(&capture_enabled_, enabled); +} + +// static +void AllocationContextTracker::PushPseudoStackFrame(StackFrame frame) { + auto tracker = AllocationContextTracker::GetThreadLocalTracker(); + + // Impose a limit on the height to verify that every push is popped, because + // in practice the pseudo stack never grows higher than ~20 frames. + DCHECK_LT(tracker->pseudo_stack_.size(), 128u); + tracker->pseudo_stack_.push_back(frame); +} + +// static +void AllocationContextTracker::PopPseudoStackFrame(StackFrame frame) { + auto tracker = AllocationContextTracker::GetThreadLocalTracker(); + + // Guard for stack underflow. If tracing was started with a TRACE_EVENT in + // scope, the frame was never pushed, so it is possible that pop is called + // on an empty stack. + if (tracker->pseudo_stack_.empty()) + return; + + // Assert that pushes and pops are nested correctly. This DCHECK can be + // hit if some TRACE_EVENT macro is unbalanced (a TRACE_EVENT_END* call + // without a corresponding TRACE_EVENT_BEGIN). + DCHECK_EQ(frame, tracker->pseudo_stack_.back()) + << "Encountered an unmatched TRACE_EVENT_END"; + + tracker->pseudo_stack_.pop_back(); +} + +// static +AllocationContext AllocationContextTracker::GetContextSnapshot() { + AllocationContextTracker* tracker = GetThreadLocalTracker(); + AllocationContext ctx; + + // Fill the backtrace. + { + auto src = tracker->pseudo_stack_.begin(); + auto dst = ctx.backtrace.frames; + auto src_end = tracker->pseudo_stack_.end(); + auto dst_end = End(ctx.backtrace.frames); + + // Copy as much of the bottom of the pseudo stack into the backtrace as + // possible. + for (; src != src_end && dst != dst_end; src++, dst++) + *dst = *src; + + // If there is room for more, fill the remaining slots with empty frames. + std::fill(dst, dst_end, nullptr); + } + + ctx.type_id = 0; + + return ctx; +} + +} // namespace trace_event +} // namespace base
diff --git a/base/trace_event/heap_profiler_allocation_context_tracker.h b/base/trace_event/heap_profiler_allocation_context_tracker.h new file mode 100644 index 0000000..9c9a313 --- /dev/null +++ b/base/trace_event/heap_profiler_allocation_context_tracker.h
@@ -0,0 +1,73 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_TRACE_EVENT_HEAP_PROFILER_ALLOCATION_CONTEXT_TRACKER_H_ +#define BASE_TRACE_EVENT_HEAP_PROFILER_ALLOCATION_CONTEXT_TRACKER_H_ + +#include <vector> + +#include "base/atomicops.h" +#include "base/base_export.h" +#include "base/logging.h" +#include "base/macros.h" +#include "base/trace_event/heap_profiler_allocation_context.h" + +namespace base { +namespace trace_event { + +// The allocation context tracker keeps track of thread-local context for heap +// profiling. It includes a pseudo stack of trace events. On every allocation +// the tracker provides a snapshot of its context in the form of an +// |AllocationContext| that is to be stored together with the allocation +// details. +class BASE_EXPORT AllocationContextTracker { + public: + // Globally enables capturing allocation context. + // TODO(ruuda): Should this be replaced by |EnableCapturing| in the future? + // Or at least have something that guards agains enable -> disable -> enable? + static void SetCaptureEnabled(bool enabled); + + // Returns whether capturing allocation context is enabled globally. + inline static bool capture_enabled() { + // A little lag after heap profiling is enabled or disabled is fine, it is + // more important that the check is as cheap as possible when capturing is + // not enabled, so do not issue a memory barrier in the fast path. + if (subtle::NoBarrier_Load(&capture_enabled_) == 0) + return false; + + // In the slow path, an acquire load is required to pair with the release + // store in |SetCaptureEnabled|. This is to ensure that the TLS slot for + // the thread-local allocation context tracker has been initialized if + // |capture_enabled| returns true. + return subtle::Acquire_Load(&capture_enabled_) != 0; + } + + // Pushes a frame onto the thread-local pseudo stack. + static void PushPseudoStackFrame(StackFrame frame); + + // Pops a frame from the thread-local pseudo stack. + static void PopPseudoStackFrame(StackFrame frame); + + // Returns a snapshot of the current thread-local context. + static AllocationContext GetContextSnapshot(); + + ~AllocationContextTracker(); + + private: + AllocationContextTracker(); + + static AllocationContextTracker* GetThreadLocalTracker(); + + static subtle::Atomic32 capture_enabled_; + + // The pseudo stack where frames are |TRACE_EVENT| names. + std::vector<StackFrame> pseudo_stack_; + + DISALLOW_COPY_AND_ASSIGN(AllocationContextTracker); +}; + +} // namespace trace_event +} // namespace base + +#endif // BASE_TRACE_EVENT_HEAP_PROFILER_ALLOCATION_CONTEXT_TRACKER_H_
diff --git a/base/trace_event/memory_profiler_allocation_context_unittest.cc b/base/trace_event/heap_profiler_allocation_context_tracker_unittest.cc similarity index 63% rename from base/trace_event/memory_profiler_allocation_context_unittest.cc rename to base/trace_event/heap_profiler_allocation_context_tracker_unittest.cc index ffc27b688..fe3f407 100644 --- a/base/trace_event/memory_profiler_allocation_context_unittest.cc +++ b/base/trace_event/heap_profiler_allocation_context_tracker_unittest.cc
@@ -3,7 +3,8 @@ // found in the LICENSE file. #include "base/memory/ref_counted.h" -#include "base/trace_event/memory_profiler_allocation_context.h" +#include "base/trace_event/heap_profiler_allocation_context.h" +#include "base/trace_event/heap_profiler_allocation_context_tracker.h" #include "base/trace_event/trace_event.h" #include "testing/gtest/include/gtest/gtest.h" @@ -18,12 +19,6 @@ const char kFroyo[] = "Froyo"; const char kGingerbread[] = "Gingerbread"; -const char kBrowserMain[] = "BrowserMain"; -const char kRendererMain[] = "RendererMain"; -const char kCreateWidget[] = "CreateWidget"; -const char kInitialize[] = "Initialize"; -const char kMalloc[] = "malloc"; - // Returns a pointer past the end of the fixed-size array |array| of |T| of // length |N|, identical to C++11 |std::end|. template <typename T, int N> @@ -60,7 +55,7 @@ ASSERT_EQ(nullptr, frame); } -class AllocationContextTest : public testing::Test { +class AllocationContextTrackerTest : public testing::Test { public: void SetUp() override { TraceConfig config(""); @@ -74,12 +69,10 @@ } }; -class StackFrameDeduplicatorTest : public testing::Test {}; - // Check that |TRACE_EVENT| macros push and pop to the pseudo stack correctly. // Also check that |GetContextSnapshot| fills the backtrace with null pointers // when the pseudo stack height is less than the capacity. -TEST_F(AllocationContextTest, PseudoStackScopedTrace) { +TEST_F(AllocationContextTrackerTest, PseudoStackScopedTrace) { StackFrame c = kCupcake; StackFrame d = kDonut; StackFrame e = kEclair; @@ -122,7 +115,7 @@ // Same as |PseudoStackScopedTrace|, but now test the |TRACE_EVENT_BEGIN| and // |TRACE_EVENT_END| macros. -TEST_F(AllocationContextTest, PseudoStackBeginEndTrace) { +TEST_F(AllocationContextTrackerTest, PseudoStackBeginEndTrace) { StackFrame c = kCupcake; StackFrame d = kDonut; StackFrame e = kEclair; @@ -160,7 +153,7 @@ AssertBacktraceEmpty(); } -TEST_F(AllocationContextTest, PseudoStackMixedTrace) { +TEST_F(AllocationContextTrackerTest, PseudoStackMixedTrace) { StackFrame c = kCupcake; StackFrame d = kDonut; StackFrame e = kEclair; @@ -198,7 +191,7 @@ AssertBacktraceEmpty(); } -TEST_F(AllocationContextTest, BacktraceTakesTop) { +TEST_F(AllocationContextTrackerTest, BacktraceTakesTop) { // Push 12 events onto the pseudo stack. TRACE_EVENT0("Testing", kCupcake); TRACE_EVENT0("Testing", kCupcake); @@ -231,102 +224,5 @@ } } -TEST_F(StackFrameDeduplicatorTest, SingleBacktrace) { - Backtrace bt = { - {kBrowserMain, kCreateWidget, kMalloc, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; - - // The call tree should look like this (index in brackets). - // - // BrowserMain [0] - // + CreateWidget [1] - // + malloc [2] - - scoped_refptr<StackFrameDeduplicator> dedup = new StackFrameDeduplicator; - ASSERT_EQ(2, dedup->Insert(bt)); - - auto iter = dedup->begin(); - ASSERT_EQ(kBrowserMain, (iter + 0)->frame); - ASSERT_EQ(-1, (iter + 0)->parent_frame_index); - - ASSERT_EQ(kCreateWidget, (iter + 1)->frame); - ASSERT_EQ(0, (iter + 1)->parent_frame_index); - - ASSERT_EQ(kMalloc, (iter + 2)->frame); - ASSERT_EQ(1, (iter + 2)->parent_frame_index); - - ASSERT_EQ(iter + 3, dedup->end()); -} - -// Test that there can be different call trees (there can be multiple bottom -// frames). Also verify that frames with the same name but a different caller -// are represented as distinct nodes. -TEST_F(StackFrameDeduplicatorTest, MultipleRoots) { - Backtrace bt0 = {{kBrowserMain, kCreateWidget, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; - Backtrace bt1 = {{kRendererMain, kCreateWidget, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; - - // The call tree should look like this (index in brackets). - // - // BrowserMain [0] - // + CreateWidget [1] - // RendererMain [2] - // + CreateWidget [3] - // - // Note that there will be two instances of Donut, with different parents. - - scoped_refptr<StackFrameDeduplicator> dedup = new StackFrameDeduplicator; - ASSERT_EQ(1, dedup->Insert(bt0)); - ASSERT_EQ(3, dedup->Insert(bt1)); - - auto iter = dedup->begin(); - ASSERT_EQ(kBrowserMain, (iter + 0)->frame); - ASSERT_EQ(-1, (iter + 0)->parent_frame_index); - - ASSERT_EQ(kCreateWidget, (iter + 1)->frame); - ASSERT_EQ(0, (iter + 1)->parent_frame_index); - - ASSERT_EQ(kRendererMain, (iter + 2)->frame); - ASSERT_EQ(-1, (iter + 2)->parent_frame_index); - - ASSERT_EQ(kCreateWidget, (iter + 3)->frame); - ASSERT_EQ(2, (iter + 3)->parent_frame_index); - - ASSERT_EQ(iter + 4, dedup->end()); -} - -TEST_F(StackFrameDeduplicatorTest, Deduplication) { - Backtrace bt0 = {{kBrowserMain, kCreateWidget, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; - Backtrace bt1 = {{kBrowserMain, kInitialize, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; - - // The call tree should look like this (index in brackets). - // - // BrowserMain [0] - // + CreateWidget [1] - // + Initialize [2] - // - // Note that Cupcake will be re-used. - - scoped_refptr<StackFrameDeduplicator> dedup = new StackFrameDeduplicator; - ASSERT_EQ(1, dedup->Insert(bt0)); - ASSERT_EQ(2, dedup->Insert(bt1)); - - auto iter = dedup->begin(); - ASSERT_EQ(kBrowserMain, (iter + 0)->frame); - ASSERT_EQ(-1, (iter + 0)->parent_frame_index); - - ASSERT_EQ(kCreateWidget, (iter + 1)->frame); - ASSERT_EQ(0, (iter + 1)->parent_frame_index); - - ASSERT_EQ(kInitialize, (iter + 2)->frame); - ASSERT_EQ(0, (iter + 2)->parent_frame_index); - - ASSERT_EQ(iter + 3, dedup->end()); - - // Inserting the same backtrace again should return the index of the existing - // node. - ASSERT_EQ(1, dedup->Insert(bt0)); - ASSERT_EQ(2, dedup->Insert(bt1)); - ASSERT_EQ(dedup->begin() + 3, dedup->end()); -} - } // namespace trace_event } // namespace base
diff --git a/base/trace_event/memory_profiler_allocation_register.cc b/base/trace_event/heap_profiler_allocation_register.cc similarity index 97% rename from base/trace_event/memory_profiler_allocation_register.cc rename to base/trace_event/heap_profiler_allocation_register.cc index 4421c0a..37647ee 100644 --- a/base/trace_event/memory_profiler_allocation_register.cc +++ b/base/trace_event/heap_profiler_allocation_register.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/trace_event/memory_profiler_allocation_register.h" +#include "base/trace_event/heap_profiler_allocation_register.h" #include "base/trace_event/trace_event_memory_overhead.h" @@ -113,7 +113,7 @@ // The list head is in |buckets_| at the hash offset. CellIndex* idx_ptr = &buckets_[Hash(address)]; - // Chase down the list until the cell that holds |key| is found, + // Chase down the list until the cell that holds |address| is found, // or until the list ends. while (*idx_ptr != 0 && cells_[*idx_ptr].allocation.address != address) idx_ptr = &cells_[*idx_ptr].next;
diff --git a/base/trace_event/memory_profiler_allocation_register.h b/base/trace_event/heap_profiler_allocation_register.h similarity index 93% rename from base/trace_event/memory_profiler_allocation_register.h rename to base/trace_event/heap_profiler_allocation_register.h index 8eb4a9d5..7c4ba99 100644 --- a/base/trace_event/memory_profiler_allocation_register.h +++ b/base/trace_event/heap_profiler_allocation_register.h
@@ -2,13 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef BASE_TRACE_EVENT_MEMORY_PROFILER_ALLOCATION_REGISTER_H_ -#define BASE_TRACE_EVENT_MEMORY_PROFILER_ALLOCATION_REGISTER_H_ +#ifndef BASE_TRACE_EVENT_HEAP_PROFILER_ALLOCATION_REGISTER_H_ +#define BASE_TRACE_EVENT_HEAP_PROFILER_ALLOCATION_REGISTER_H_ #include <stdint.h> #include "base/logging.h" -#include "base/trace_event/memory_profiler_allocation_context.h" +#include "base/macros.h" +#include "base/trace_event/heap_profiler_allocation_context.h" namespace base { namespace trace_event { @@ -116,9 +117,9 @@ // Returns a value in the range [0, kNumBuckets - 1] (inclusive). static uint32_t Hash(void* address); - // Allocates a region of virtual address space of |min_size| rounded up to the - // system page size. The memory is zeroed by the system. A guard page is added - // after the end. + // Allocates a region of virtual address space of |size| rounded up to the + // system page size. The memory is zeroed by the system. A guard page is + // added after the end. static void* AllocateVirtualMemory(size_t size); // Frees a region of virtual address space allocated by a call to @@ -142,7 +143,7 @@ Cell* const cells_; // The array of indices into |cells_|. |buckets_[Hash(address)]| will contain - // the index of the head of the linked list for |Hash(key)|. A value of 0 + // the index of the head of the linked list for |Hash(address)|. A value of 0 // indicates an empty list. This array is backed by mmapped memory. CellIndex* const buckets_; @@ -161,4 +162,4 @@ } // namespace trace_event } // namespace base -#endif // BASE_TRACE_EVENT_MEMORY_PROFILER_ALLOCATION_REGISTER_H_ +#endif // BASE_TRACE_EVENT_HEAP_PROFILER_ALLOCATION_REGISTER_H_
diff --git a/base/trace_event/memory_profiler_allocation_register_posix.cc b/base/trace_event/heap_profiler_allocation_register_posix.cc similarity index 95% rename from base/trace_event/memory_profiler_allocation_register_posix.cc rename to base/trace_event/heap_profiler_allocation_register_posix.cc index e2231a8..bc175e4 100644 --- a/base/trace_event/memory_profiler_allocation_register_posix.cc +++ b/base/trace_event/heap_profiler_allocation_register_posix.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/trace_event/memory_profiler_allocation_register.h" +#include "base/trace_event/heap_profiler_allocation_register.h" #include <sys/mman.h> #include <unistd.h>
diff --git a/base/trace_event/memory_profiler_allocation_register_unittest.cc b/base/trace_event/heap_profiler_allocation_register_unittest.cc similarity index 98% rename from base/trace_event/memory_profiler_allocation_register_unittest.cc rename to base/trace_event/heap_profiler_allocation_register_unittest.cc index bb5aeb3..f17ffbcf 100644 --- a/base/trace_event/memory_profiler_allocation_register_unittest.cc +++ b/base/trace_event/heap_profiler_allocation_register_unittest.cc
@@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/trace_event/memory_profiler_allocation_register.h" +#include "base/trace_event/heap_profiler_allocation_register.h" #include "base/process/process_metrics.h" +#include "base/trace_event/heap_profiler_allocation_context.h" #include "testing/gtest/include/gtest/gtest.h" namespace base {
diff --git a/base/trace_event/memory_profiler_allocation_register_win.cc b/base/trace_event/heap_profiler_allocation_register_win.cc similarity index 96% rename from base/trace_event/memory_profiler_allocation_register_win.cc rename to base/trace_event/heap_profiler_allocation_register_win.cc index b94c75e..5bcac63 100644 --- a/base/trace_event/memory_profiler_allocation_register_win.cc +++ b/base/trace_event/heap_profiler_allocation_register_win.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/trace_event/memory_profiler_allocation_register.h" +#include "base/trace_event/heap_profiler_allocation_register.h" #include <windows.h>
diff --git a/base/trace_event/memory_profiler_heap_dump_writer.cc b/base/trace_event/heap_profiler_heap_dump_writer.cc similarity index 88% rename from base/trace_event/memory_profiler_heap_dump_writer.cc rename to base/trace_event/heap_profiler_heap_dump_writer.cc index 60e9929..16316505 100644 --- a/base/trace_event/memory_profiler_heap_dump_writer.cc +++ b/base/trace_event/heap_profiler_heap_dump_writer.cc
@@ -2,14 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/trace_event/memory_profiler_heap_dump_writer.h" +#include "base/trace_event/heap_profiler_heap_dump_writer.h" #include <algorithm> #include <iterator> +#include <utility> +#include <vector> #include "base/format_macros.h" #include "base/strings/stringprintf.h" -#include "base/trace_event/memory_profiler_allocation_register.h" +#include "base/trace_event/heap_profiler_stack_frame_deduplicator.h" #include "base/trace_event/trace_event_argument.h" namespace base { @@ -25,8 +27,10 @@ return lhs.second > rhs.second; } +// Converts a |hash_map<T, size_t>| into a vector of (T, size_t) pairs that is +// ordered from high |size_t| to low |size_t|. template <typename T> -std::vector<std::pair<T, size_t>> SortDescending( +std::vector<std::pair<T, size_t>> SortBySizeDescending( const hash_map<T, size_t>& grouped) { std::vector<std::pair<T, size_t>> sorted; std::copy(grouped.begin(), grouped.end(), std::back_inserter(sorted)); @@ -60,9 +64,8 @@ bytes_by_type[context_size.first.type_id] += context_size.second; } - // Sort the backtraces and type IDs by size. - auto sorted_bytes_by_backtrace = SortDescending(bytes_by_backtrace); - auto sorted_bytes_by_type = SortDescending(bytes_by_type); + auto sorted_bytes_by_backtrace = SortBySizeDescending(bytes_by_backtrace); + auto sorted_bytes_by_type = SortBySizeDescending(bytes_by_type); traced_value_->BeginArray("entries");
diff --git a/base/trace_event/memory_profiler_heap_dump_writer.h b/base/trace_event/heap_profiler_heap_dump_writer.h similarity index 89% rename from base/trace_event/memory_profiler_heap_dump_writer.h rename to base/trace_event/heap_profiler_heap_dump_writer.h index 10a64e5..4b995433 100644 --- a/base/trace_event/memory_profiler_heap_dump_writer.h +++ b/base/trace_event/heap_profiler_heap_dump_writer.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef BASE_TRACE_EVENT_MEMORY_PROFILER_HEAP_DUMP_WRITER_H_ -#define BASE_TRACE_EVENT_MEMORY_PROFILER_HEAP_DUMP_WRITER_H_ +#ifndef BASE_TRACE_EVENT_HEAP_PROFILER_HEAP_DUMP_WRITER_H_ +#define BASE_TRACE_EVENT_HEAP_PROFILER_HEAP_DUMP_WRITER_H_ #include <string> @@ -11,13 +11,13 @@ #include "base/containers/hash_tables.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/trace_event/memory_profiler_allocation_context.h" +#include "base/trace_event/heap_profiler_allocation_context.h" namespace base { namespace trace_event { -class AllocationRegister; class TracedValue; +class StackFrameDeduplicator; // Helper class to dump a snapshot of an |AllocationRegister| or other heap // bookkeeping structure into a |TracedValue|. This class is intended to be @@ -72,4 +72,4 @@ } // namespace trace_event } // namespace base -#endif // BASE_TRACE_EVENT_MEMORY_PROFILER_HEAP_DUMP_WRITER_H_ +#endif // BASE_TRACE_EVENT_HEAP_PROFILER_HEAP_DUMP_WRITER_H_
diff --git a/base/trace_event/heap_profiler_stack_frame_deduplicator.cc b/base/trace_event/heap_profiler_stack_frame_deduplicator.cc new file mode 100644 index 0000000..09c4a3e --- /dev/null +++ b/base/trace_event/heap_profiler_stack_frame_deduplicator.cc
@@ -0,0 +1,112 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/trace_event/heap_profiler_stack_frame_deduplicator.h" + +#include <string> +#include <utility> + +#include "base/strings/stringprintf.h" +#include "base/trace_event/trace_event_argument.h" +#include "base/trace_event/trace_event_memory_overhead.h" + +namespace base { +namespace trace_event { + +StackFrameDeduplicator::FrameNode::FrameNode(StackFrame frame, + int parent_frame_index) + : frame(frame), parent_frame_index(parent_frame_index) {} +StackFrameDeduplicator::FrameNode::~FrameNode() {} + +StackFrameDeduplicator::StackFrameDeduplicator() {} +StackFrameDeduplicator::~StackFrameDeduplicator() {} + +int StackFrameDeduplicator::Insert(const Backtrace& bt) { + int frame_index = -1; + std::map<StackFrame, int>* nodes = &roots_; + + for (size_t i = 0; i < arraysize(bt.frames); i++) { + if (!bt.frames[i]) + break; + + auto node = nodes->find(bt.frames[i]); + if (node == nodes->end()) { + // There is no tree node for this frame yet, create it. The parent node + // is the node associated with the previous frame. + FrameNode frame_node(bt.frames[i], frame_index); + + // The new frame node will be appended, so its index is the current size + // of the vector. + frame_index = static_cast<int>(frames_.size()); + + // Add the node to the trie so it will be found next time. + nodes->insert(std::make_pair(bt.frames[i], frame_index)); + + // Append the node after modifying |nodes|, because the |frames_| vector + // might need to resize, and this invalidates the |nodes| pointer. + frames_.push_back(frame_node); + } else { + // A tree node for this frame exists. Look for the next one. + frame_index = node->second; + } + + nodes = &frames_[frame_index].children; + } + + return frame_index; +} + +void StackFrameDeduplicator::AppendAsTraceFormat(std::string* out) const { + out->append("{"); // Begin the |stackFrames| dictionary. + + int i = 0; + auto frame_node = begin(); + auto it_end = end(); + std::string stringify_buffer; + + while (frame_node != it_end) { + // The |stackFrames| format is a dictionary, not an array, so the + // keys are stringified indices. Write the index manually, then use + // |TracedValue| to format the object. This is to avoid building the + // entire dictionary as a |TracedValue| in memory. + SStringPrintf(&stringify_buffer, "\"%d\":", i); + out->append(stringify_buffer); + + scoped_refptr<TracedValue> frame_node_value = new TracedValue; + frame_node_value->SetString("name", frame_node->frame); + if (frame_node->parent_frame_index >= 0) { + SStringPrintf(&stringify_buffer, "%d", frame_node->parent_frame_index); + frame_node_value->SetString("parent", stringify_buffer); + } + frame_node_value->AppendAsTraceFormat(out); + + i++; + frame_node++; + + if (frame_node != it_end) + out->append(","); + } + + out->append("}"); // End the |stackFrames| dictionary. +} + +void StackFrameDeduplicator::EstimateTraceMemoryOverhead( + TraceEventMemoryOverhead* overhead) { + // The sizes here are only estimates; they fail to take into account the + // overhead of the tree nodes for the map, but as an estimate this should be + // fine. + size_t maps_size = roots_.size() * sizeof(std::pair<StackFrame, int>); + size_t frames_allocated = frames_.capacity() * sizeof(FrameNode); + size_t frames_resident = frames_.size() * sizeof(FrameNode); + + for (const FrameNode& node : frames_) + maps_size += node.children.size() * sizeof(std::pair<StackFrame, int>); + + overhead->Add("StackFrameDeduplicator", + sizeof(StackFrameDeduplicator) + maps_size + frames_allocated, + sizeof(StackFrameDeduplicator) + maps_size + frames_resident); +} + +} // namespace trace_event +} // namespace base
diff --git a/base/trace_event/heap_profiler_stack_frame_deduplicator.h b/base/trace_event/heap_profiler_stack_frame_deduplicator.h new file mode 100644 index 0000000..a7b00ca --- /dev/null +++ b/base/trace_event/heap_profiler_stack_frame_deduplicator.h
@@ -0,0 +1,77 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_TRACE_EVENT_HEAP_PROFILER_STACK_FRAME_DEDUPLICATOR_H_ +#define BASE_TRACE_EVENT_HEAP_PROFILER_STACK_FRAME_DEDUPLICATOR_H_ + +#include <map> +#include <string> +#include <vector> + +#include "base/base_export.h" +#include "base/macros.h" +#include "base/trace_event/heap_profiler_allocation_context.h" +#include "base/trace_event/trace_event_impl.h" + +namespace base { +namespace trace_event { + +class TraceEventMemoryOverhead; + +// A data structure that allows grouping a set of backtraces in a space- +// efficient manner by creating a call tree and writing it as a set of (node, +// parent) pairs. The tree nodes reference both parent and children. The parent +// is referenced by index into |frames_|. The children are referenced via a map +// of |StackFrame|s to index into |frames_|. So there is a trie for bottum-up +// lookup of a backtrace for deduplication, and a tree for compact storage in +// the trace log. +class BASE_EXPORT StackFrameDeduplicator : public ConvertableToTraceFormat { + public: + // A node in the call tree. + struct FrameNode { + FrameNode(StackFrame frame, int parent_frame_index); + ~FrameNode(); + + StackFrame frame; + + // The index of the parent stack frame in |frames_|, or -1 if there is no + // parent frame (when it is at the bottom of the call stack). + int parent_frame_index; + + // Indices into |frames_| of frames called from the current frame. + std::map<StackFrame, int> children; + }; + + using ConstIterator = std::vector<FrameNode>::const_iterator; + + StackFrameDeduplicator(); + + // Inserts a backtrace and returns the index of its leaf node in |frames_|. + // Returns -1 if the backtrace is empty. + int Insert(const Backtrace& bt); + + // Iterators over the frame nodes in the call tree. + ConstIterator begin() const { return frames_.begin(); } + ConstIterator end() const { return frames_.end(); } + + // Writes the |stackFrames| dictionary as defined in https://goo.gl/GerkV8 to + // the trace log. + void AppendAsTraceFormat(std::string* out) const override; + + // Estimates memory overhead including |sizeof(StackFrameDeduplicator)|. + void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead) override; + + private: + ~StackFrameDeduplicator() override; + + std::map<StackFrame, int> roots_; + std::vector<FrameNode> frames_; + + DISALLOW_COPY_AND_ASSIGN(StackFrameDeduplicator); +}; + +} // namespace trace_event +} // namespace base + +#endif // BASE_TRACE_EVENT_HEAP_PROFILER_STACK_FRAME_DEDUPLICATOR_H_
diff --git a/base/trace_event/heap_profiler_stack_frame_deduplicator_unittest.cc b/base/trace_event/heap_profiler_stack_frame_deduplicator_unittest.cc new file mode 100644 index 0000000..b87c7b1 --- /dev/null +++ b/base/trace_event/heap_profiler_stack_frame_deduplicator_unittest.cc
@@ -0,0 +1,122 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/memory/ref_counted.h" +#include "base/trace_event/heap_profiler_allocation_context.h" +#include "base/trace_event/heap_profiler_stack_frame_deduplicator.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace base { +namespace trace_event { + +// Define all strings once, because the deduplicator requires pointer equality, +// and string interning is unreliable. +const char kBrowserMain[] = "BrowserMain"; +const char kRendererMain[] = "RendererMain"; +const char kCreateWidget[] = "CreateWidget"; +const char kInitialize[] = "Initialize"; +const char kMalloc[] = "malloc"; + +class StackFrameDeduplicatorTest : public testing::Test {}; + +TEST_F(StackFrameDeduplicatorTest, SingleBacktrace) { + Backtrace bt = { + {kBrowserMain, kCreateWidget, kMalloc, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; + + // The call tree should look like this (index in brackets). + // + // BrowserMain [0] + // CreateWidget [1] + // malloc [2] + + scoped_refptr<StackFrameDeduplicator> dedup = new StackFrameDeduplicator; + ASSERT_EQ(2, dedup->Insert(bt)); + + auto iter = dedup->begin(); + ASSERT_EQ(kBrowserMain, (iter + 0)->frame); + ASSERT_EQ(-1, (iter + 0)->parent_frame_index); + + ASSERT_EQ(kCreateWidget, (iter + 1)->frame); + ASSERT_EQ(0, (iter + 1)->parent_frame_index); + + ASSERT_EQ(kMalloc, (iter + 2)->frame); + ASSERT_EQ(1, (iter + 2)->parent_frame_index); + + ASSERT_EQ(iter + 3, dedup->end()); +} + +// Test that there can be different call trees (there can be multiple bottom +// frames). Also verify that frames with the same name but a different caller +// are represented as distinct nodes. +TEST_F(StackFrameDeduplicatorTest, MultipleRoots) { + Backtrace bt0 = {{kBrowserMain, kCreateWidget, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; + Backtrace bt1 = {{kRendererMain, kCreateWidget, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; + + // The call tree should look like this (index in brackets). + // + // BrowserMain [0] + // CreateWidget [1] + // RendererMain [2] + // CreateWidget [3] + // + // Note that there will be two instances of CreateWidget, + // with different parents. + + scoped_refptr<StackFrameDeduplicator> dedup = new StackFrameDeduplicator; + ASSERT_EQ(1, dedup->Insert(bt0)); + ASSERT_EQ(3, dedup->Insert(bt1)); + + auto iter = dedup->begin(); + ASSERT_EQ(kBrowserMain, (iter + 0)->frame); + ASSERT_EQ(-1, (iter + 0)->parent_frame_index); + + ASSERT_EQ(kCreateWidget, (iter + 1)->frame); + ASSERT_EQ(0, (iter + 1)->parent_frame_index); + + ASSERT_EQ(kRendererMain, (iter + 2)->frame); + ASSERT_EQ(-1, (iter + 2)->parent_frame_index); + + ASSERT_EQ(kCreateWidget, (iter + 3)->frame); + ASSERT_EQ(2, (iter + 3)->parent_frame_index); + + ASSERT_EQ(iter + 4, dedup->end()); +} + +TEST_F(StackFrameDeduplicatorTest, Deduplication) { + Backtrace bt0 = {{kBrowserMain, kCreateWidget, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; + Backtrace bt1 = {{kBrowserMain, kInitialize, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; + + // The call tree should look like this (index in brackets). + // + // BrowserMain [0] + // CreateWidget [1] + // Initialize [2] + // + // Note that BrowserMain will be re-used. + + scoped_refptr<StackFrameDeduplicator> dedup = new StackFrameDeduplicator; + ASSERT_EQ(1, dedup->Insert(bt0)); + ASSERT_EQ(2, dedup->Insert(bt1)); + + auto iter = dedup->begin(); + ASSERT_EQ(kBrowserMain, (iter + 0)->frame); + ASSERT_EQ(-1, (iter + 0)->parent_frame_index); + + ASSERT_EQ(kCreateWidget, (iter + 1)->frame); + ASSERT_EQ(0, (iter + 1)->parent_frame_index); + + ASSERT_EQ(kInitialize, (iter + 2)->frame); + ASSERT_EQ(0, (iter + 2)->parent_frame_index); + + ASSERT_EQ(iter + 3, dedup->end()); + + // Inserting the same backtrace again should return the index of the existing + // node. + ASSERT_EQ(1, dedup->Insert(bt0)); + ASSERT_EQ(2, dedup->Insert(bt1)); + ASSERT_EQ(dedup->begin() + 3, dedup->end()); +} + +} // namespace trace_event +} // namespace base
diff --git a/base/trace_event/memory_dump_manager.cc b/base/trace_event/memory_dump_manager.cc index 19bdcc4..354d782 100644 --- a/base/trace_event/memory_dump_manager.cc +++ b/base/trace_event/memory_dump_manager.cc
@@ -12,10 +12,11 @@ #include "base/compiler_specific.h" #include "base/thread_task_runner_handle.h" #include "base/threading/thread.h" +#include "base/trace_event/heap_profiler_allocation_context_tracker.h" +#include "base/trace_event/heap_profiler_stack_frame_deduplicator.h" #include "base/trace_event/malloc_dump_provider.h" #include "base/trace_event/memory_dump_provider.h" #include "base/trace_event/memory_dump_session_state.h" -#include "base/trace_event/memory_profiler_allocation_context.h" #include "base/trace_event/process_memory_dump.h" #include "base/trace_event/trace_event_argument.h" #include "build/build_config.h"
diff --git a/base/trace_event/memory_dump_session_state.h b/base/trace_event/memory_dump_session_state.h index 84d07334..8a032079 100644 --- a/base/trace_event/memory_dump_session_state.h +++ b/base/trace_event/memory_dump_session_state.h
@@ -5,17 +5,13 @@ #ifndef BASE_TRACE_EVENT_MEMORY_DUMP_SESSION_STATE_H_ #define BASE_TRACE_EVENT_MEMORY_DUMP_SESSION_STATE_H_ -#include <string> - #include "base/base_export.h" #include "base/memory/ref_counted.h" -#include "base/trace_event/memory_profiler_allocation_context.h" +#include "base/trace_event/heap_profiler_stack_frame_deduplicator.h" namespace base { namespace trace_event { -class StackFrameDeduplicator; - // Container for state variables that should be shared across all the memory // dumps in a tracing session. class BASE_EXPORT MemoryDumpSessionState
diff --git a/base/trace_event/memory_profiler_allocation_context.cc b/base/trace_event/memory_profiler_allocation_context.cc deleted file mode 100644 index ed8d759..0000000 --- a/base/trace_event/memory_profiler_allocation_context.cc +++ /dev/null
@@ -1,234 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/trace_event/memory_profiler_allocation_context.h" - -#include <algorithm> -#include <cstring> - -#include "base/hash.h" -#include "base/strings/stringprintf.h" -#include "base/threading/thread_local_storage.h" -#include "base/trace_event/trace_event_argument.h" -#include "base/trace_event/trace_event_memory_overhead.h" - -namespace base { -namespace trace_event { - -subtle::Atomic32 AllocationContextTracker::capture_enabled_ = 0; - -namespace { - -ThreadLocalStorage::StaticSlot g_tls_alloc_ctx_tracker = TLS_INITIALIZER; - -// This function is added to the TLS slot to clean up the instance when the -// thread exits. -void DestructAllocationContextTracker(void* alloc_ctx_tracker) { - delete static_cast<AllocationContextTracker*>(alloc_ctx_tracker); -} - -} // namespace - -AllocationStack::AllocationStack() {} -AllocationStack::~AllocationStack() {} - -bool operator==(const Backtrace& lhs, const Backtrace& rhs) { - // Pointer equality of the stack frames is assumed, so instead of doing a deep - // string comparison on all of the frames, a |memcmp| suffices. - return std::memcmp(lhs.frames, rhs.frames, sizeof(lhs.frames)) == 0; -} - -StackFrameDeduplicator::FrameNode::FrameNode(StackFrame frame, - int parent_frame_index) - : frame(frame), parent_frame_index(parent_frame_index) {} -StackFrameDeduplicator::FrameNode::~FrameNode() {} - -StackFrameDeduplicator::StackFrameDeduplicator() {} -StackFrameDeduplicator::~StackFrameDeduplicator() {} - -int StackFrameDeduplicator::Insert(const Backtrace& bt) { - int frame_index = -1; - std::map<StackFrame, int>* nodes = &roots_; - - for (size_t i = 0; i < arraysize(bt.frames); i++) { - if (!bt.frames[i]) - break; - - auto node = nodes->find(bt.frames[i]); - if (node == nodes->end()) { - // There is no tree node for this frame yet, create it. The parent node - // is the node associated with the previous frame. - FrameNode frame_node(bt.frames[i], frame_index); - - // The new frame node will be appended, so its index is the current size - // of the vector. - frame_index = static_cast<int>(frames_.size()); - - // Add the node to the trie so it will be found next time. - nodes->insert(std::make_pair(bt.frames[i], frame_index)); - - // Append the node after modifying |children|, because the vector might - // need to resize, and this invalidates the |children| pointer. - frames_.push_back(frame_node); - } else { - // A tree node for this frame exists. Look for the next one. - frame_index = node->second; - } - - nodes = &frames_[frame_index].children; - } - - return frame_index; -} - -void StackFrameDeduplicator::AppendAsTraceFormat(std::string* out) const { - out->append("{"); // Begin the |stackFrames| dictionary. - - int i = 0; - auto frame_node = begin(); - auto it_end = end(); - std::string stringify_buffer; - while (frame_node != it_end) { - // The |stackFrames| format is a dictionary, not an array, so the - // keys are stringified indices. Write the index manually, then use - // |TracedValue| to format the object. This is to avoid building the - // entire dictionary as a |TracedValue| in memory. - SStringPrintf(&stringify_buffer, "\"%d\":", i); - out->append(stringify_buffer); - - scoped_refptr<TracedValue> frame_node_value = new TracedValue; - frame_node_value->SetString("name", frame_node->frame); - if (frame_node->parent_frame_index >= 0) { - SStringPrintf(&stringify_buffer, "%d", frame_node->parent_frame_index); - frame_node_value->SetString("parent", stringify_buffer); - } - frame_node_value->AppendAsTraceFormat(out); - - i++; - frame_node++; - - if (frame_node != it_end) - out->append(","); - } - - out->append("}"); // End the |stackFrames| dictionary. -} - -void StackFrameDeduplicator::EstimateTraceMemoryOverhead( - TraceEventMemoryOverhead* overhead) { - - // The sizes here are only estimates; they fail to take into account the - // overhead of the tree nodes for the map, but as an estimate this should be - // fine. - size_t maps_size = roots_.size() * sizeof(std::pair<StackFrame, int>); - size_t frames_allocated = frames_.capacity() * sizeof(FrameNode); - size_t frames_resident = frames_.size() * sizeof(FrameNode); - - for (const FrameNode& node : frames_) - maps_size += node.children.size() * sizeof(std::pair<StackFrame, int>); - - overhead->Add("StackFrameDeduplicator", - sizeof(StackFrameDeduplicator) + maps_size + frames_allocated, - sizeof(StackFrameDeduplicator) + maps_size + frames_resident); -} - -bool operator==(const AllocationContext& lhs, const AllocationContext& rhs) { - return (lhs.backtrace == rhs.backtrace) && (lhs.type_id == rhs.type_id); -} - -AllocationContextTracker* AllocationContextTracker::GetThreadLocalTracker() { - auto tracker = - static_cast<AllocationContextTracker*>(g_tls_alloc_ctx_tracker.Get()); - - if (!tracker) { - tracker = new AllocationContextTracker(); - g_tls_alloc_ctx_tracker.Set(tracker); - } - - return tracker; -} - -AllocationContextTracker::AllocationContextTracker() {} -AllocationContextTracker::~AllocationContextTracker() {} - -// static -void AllocationContextTracker::SetCaptureEnabled(bool enabled) { - // When enabling capturing, also initialize the TLS slot. This does not create - // a TLS instance yet. - if (enabled && !g_tls_alloc_ctx_tracker.initialized()) - g_tls_alloc_ctx_tracker.Initialize(DestructAllocationContextTracker); - - // Release ordering ensures that when a thread observes |capture_enabled_| to - // be true through an acquire load, the TLS slot has been initialized. - subtle::Release_Store(&capture_enabled_, enabled); -} - -// static -void AllocationContextTracker::PushPseudoStackFrame(StackFrame frame) { - auto tracker = AllocationContextTracker::GetThreadLocalTracker(); - tracker->pseudo_stack_.push(frame); -} - -// static -void AllocationContextTracker::PopPseudoStackFrame(StackFrame frame) { - auto tracker = AllocationContextTracker::GetThreadLocalTracker(); - tracker->pseudo_stack_.pop(frame); -} - -// Returns a pointer past the end of the fixed-size array |array| of |T| of -// length |N|, identical to C++11 |std::end|. -template <typename T, int N> -T* End(T(&array)[N]) { - return array + N; -} - -// static -AllocationContext AllocationContextTracker::GetContextSnapshot() { - AllocationContextTracker* tracker = GetThreadLocalTracker(); - AllocationContext ctx; - - // Fill the backtrace. - { - auto src = tracker->pseudo_stack_.bottom(); - auto dst = ctx.backtrace.frames; - auto src_end = tracker->pseudo_stack_.top(); - auto dst_end = End(ctx.backtrace.frames); - - // Copy as much of the bottom of the pseudo stack into the backtrace as - // possible. - for (; src != src_end && dst != dst_end; src++, dst++) - *dst = *src; - - // If there is room for more, fill the remaining slots with empty frames. - std::fill(dst, dst_end, nullptr); - } - - ctx.type_id = 0; - - return ctx; -} - -} // namespace trace_event -} // namespace base - -namespace BASE_HASH_NAMESPACE { -using base::trace_event::AllocationContext; -using base::trace_event::Backtrace; - -size_t hash<Backtrace>::operator()(const Backtrace& backtrace) const { - return base::SuperFastHash(reinterpret_cast<const char*>(backtrace.frames), - sizeof(backtrace.frames)); -} - -size_t hash<AllocationContext>::operator()(const AllocationContext& ctx) const { - size_t ctx_hash = hash<Backtrace>()(ctx.backtrace); - - // Multiply one side to break the commutativity of +. Multiplication with a - // number coprime to |numeric_limits<size_t>::max() + 1| is bijective so - // randomness is preserved. The type ID is assumed to be distributed randomly - // already so there is no need to hash it. - return (ctx_hash * 3) + static_cast<size_t>(ctx.type_id); -} - -} // BASE_HASH_NAMESPACE
diff --git a/base/trace_event/memory_profiler_allocation_context.h b/base/trace_event/memory_profiler_allocation_context.h deleted file mode 100644 index 9063663..0000000 --- a/base/trace_event/memory_profiler_allocation_context.h +++ /dev/null
@@ -1,233 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_TRACE_EVENT_MEMORY_PROFILER_ALLOCATION_CONTEXT_H_ -#define BASE_TRACE_EVENT_MEMORY_PROFILER_ALLOCATION_CONTEXT_H_ - -#include <map> -#include <string> -#include <vector> - -#include "base/atomicops.h" -#include "base/base_export.h" -#include "base/trace_event/trace_event_impl.h" - -namespace base { -namespace trace_event { - -class TraceEventMemoryOverhead; - -// When heap profiling is enabled, tracing keeps track of the allocation -// context for each allocation intercepted. It is generated by the -// |AllocationContextTracker| which keeps stacks of context in TLS. -// The tracker is initialized lazily. - -using StackFrame = const char*; - -// A simple stack of |StackFrame| that unlike |std::stack| allows iterating -// the stack and guards for underflow. -class BASE_EXPORT AllocationStack { - public: - // Incrementing the iterator iterates up the stack, from bottom (least recent - // call) to top (most recent call). - using ConstIterator = std::vector<StackFrame>::const_iterator; - - AllocationStack(); - ~AllocationStack(); - - inline ConstIterator bottom() const { return stack_.begin(); } - inline ConstIterator top() const { return stack_.end(); } - - inline void push(StackFrame frame) { - // Impose a limit on the height to verify that every push is popped, because - // in practice the pseudo stack never grows higher than ~20 frames. - DCHECK_LT(stack_.size(), 128u); - stack_.push_back(frame); - } - - inline void pop(StackFrame frame) { - if (stack_.empty()) - return; - - // Assert that pushes and pops are nested correctly. - // This DCHECK can be hit if some TRACE_EVENT macro is unbalanced - // (a TRACE_EVENT_END* call without a corresponding TRACE_EVENT_BEGIN). - DCHECK_EQ(frame, stack_.back()) - << "Encountered an unmatched TRACE_EVENT_END"; - - stack_.pop_back(); - } - - private: - std::vector<StackFrame> stack_; - - DISALLOW_COPY_AND_ASSIGN(AllocationStack); -}; - -// The backtrace in the allocation context is a snapshot of the stack. For now, -// this is the pseudo stack where frames are created by trace event macros. In -// the future, we might add the option to use the native call stack. In that -// case, |Backtrace| and |AllocationContextTracker::GetContextSnapshot| might -// have different implementations that can be selected by a compile time flag. - -// The number of stack frames stored in the backtrace is a trade off between -// memory used for tracing and accuracy. Measurements done on a prototype -// revealed that: -// -// - In 60 percent of the cases, stack depth <= 7. -// - In 87 percent of the cases, stack depth <= 9. -// - In 95 percent of the cases, stack depth <= 11. -// -// See the design doc (https://goo.gl/4s7v7b) for more details. - -struct BASE_EXPORT Backtrace { - // Unused backtrace frames are filled with nullptr frames. If the stack is - // higher than what can be stored here, the bottom frames are stored. Based - // on the data above, a depth of 12 captures the full stack in the vast - // majority of the cases. - StackFrame frames[12]; -}; - -bool BASE_EXPORT operator==(const Backtrace& lhs, const Backtrace& rhs); - -// A data structure that allows grouping a set of backtraces in a space- -// efficient manner by creating a call tree and writing it as a set of (node, -// parent) pairs. The tree nodes reference both parent and children. The parent -// is referenced by index into |frames_|. The children are referenced via a map -// of |StackFrame|s to index into |frames_|. So there is a trie for bottum-up -// lookup of a backtrace for deduplication, and a tree for compact storage in -// the trace log. -class BASE_EXPORT StackFrameDeduplicator : public ConvertableToTraceFormat { - public: - // A node in the call tree. - struct FrameNode { - FrameNode(StackFrame frame, int parent_frame_index); - ~FrameNode(); - - StackFrame frame; - - // The index of the parent stack frame in |frames_|, or -1 if there is no - // parent frame (when it is at the bottom of the call stack). - int parent_frame_index; - - // Indices into |frames_| of frames called from the current frame. - std::map<StackFrame, int> children; - }; - - using ConstIterator = std::vector<FrameNode>::const_iterator; - - StackFrameDeduplicator(); - - // Inserts a backtrace and returns the index of its leaf node in |frames_|. - // Returns -1 if the backtrace is empty. - int Insert(const Backtrace& bt); - - // Iterators over the frame nodes in the call tree. - ConstIterator begin() const { return frames_.begin(); } - ConstIterator end() const { return frames_.end(); } - - // Writes the |stackFrames| dictionary as defined in https://goo.gl/GerkV8 to - // the trace log. - void AppendAsTraceFormat(std::string* out) const override; - void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead) override; - - private: - ~StackFrameDeduplicator() override; - - std::map<StackFrame, int> roots_; - std::vector<FrameNode> frames_; - - DISALLOW_COPY_AND_ASSIGN(StackFrameDeduplicator); -}; - -// The |AllocationContext| is context metadata that is kept for every allocation -// when heap profiling is enabled. To simplify memory management for -// bookkeeping, this struct has a fixed size. All |const char*|s here -// must have static lifetime. -// TODO(ruuda): Make the default constructor private to avoid accidentally -// constructing an instance and forgetting to initialize it. Only -// |AllocationContextTracker| should be able to construct. (And tests.) -struct BASE_EXPORT AllocationContext { - // A type ID is a number that is unique for every C++ type. A type ID is - // stored instead of the type name to avoid inflating the binary with type - // name strings. There is an out of band lookup table mapping IDs to the type - // names. A value of 0 means that the type is not known. - using TypeId = uint16_t; - - Backtrace backtrace; - TypeId type_id; -}; - -bool BASE_EXPORT operator==(const AllocationContext& lhs, - const AllocationContext& rhs); - -// The allocation context tracker keeps track of thread-local context for heap -// profiling. It includes a pseudo stack of trace events. On every allocation -// the tracker provides a snapshot of its context in the form of an -// |AllocationContext| that is to be stored together with the allocation -// details. -class BASE_EXPORT AllocationContextTracker { - public: - // Globally enables capturing allocation context. - // TODO(ruuda): Should this be replaced by |EnableCapturing| in the future? - // Or at least have something that guards agains enable -> disable -> enable? - static void SetCaptureEnabled(bool enabled); - - // Returns whether capturing allocation context is enabled globally. - inline static bool capture_enabled() { - // A little lag after heap profiling is enabled or disabled is fine, it is - // more important that the check is as cheap as possible when capturing is - // not enabled, so do not issue a memory barrier in the fast path. - if (subtle::NoBarrier_Load(&capture_enabled_) == 0) - return false; - - // In the slow path, an acquire load is required to pair with the release - // store in |SetCaptureEnabled|. This is to ensure that the TLS slot for - // the thread-local allocation context tracker has been initialized if - // |capture_enabled| returns true. - return subtle::Acquire_Load(&capture_enabled_) != 0; - } - - // Pushes a frame onto the thread-local pseudo stack. - static void PushPseudoStackFrame(StackFrame frame); - - // Pops a frame from the thread-local pseudo stack. - static void PopPseudoStackFrame(StackFrame frame); - - // Returns a snapshot of the current thread-local context. - static AllocationContext GetContextSnapshot(); - - ~AllocationContextTracker(); - - private: - AllocationContextTracker(); - - static AllocationContextTracker* GetThreadLocalTracker(); - - static subtle::Atomic32 capture_enabled_; - - // The pseudo stack where frames are |TRACE_EVENT| names. - AllocationStack pseudo_stack_; - - DISALLOW_COPY_AND_ASSIGN(AllocationContextTracker); -}; - -} // namespace trace_event -} // namespace base - -namespace BASE_HASH_NAMESPACE { - -template <> -struct hash<base::trace_event::Backtrace> { - size_t operator()(const base::trace_event::Backtrace& backtrace) const; -}; - -template <> -struct hash<base::trace_event::AllocationContext> { - size_t operator()(const base::trace_event::AllocationContext& context) const; -}; - -} // BASE_HASH_NAMESPACE - -#endif // BASE_TRACE_EVENT_MEMORY_PROFILER_ALLOCATION_CONTEXT_H_
diff --git a/base/trace_event/trace_event.gypi b/base/trace_event/trace_event.gypi index 4713311..d83d65bf 100644 --- a/base/trace_event/trace_event.gypi +++ b/base/trace_event/trace_event.gypi
@@ -5,6 +5,18 @@ 'variables': { 'trace_event_sources' : [ 'trace_event/common/trace_event_common.h', + 'trace_event/heap_profiler_allocation_context.cc', + 'trace_event/heap_profiler_allocation_context.h', + 'trace_event/heap_profiler_allocation_context_tracker.cc', + 'trace_event/heap_profiler_allocation_context_tracker.h', + 'trace_event/heap_profiler_allocation_register.cc', + 'trace_event/heap_profiler_allocation_register_posix.cc', + 'trace_event/heap_profiler_allocation_register_win.cc', + 'trace_event/heap_profiler_allocation_register.h', + 'trace_event/heap_profiler_heap_dump_writer.cc', + 'trace_event/heap_profiler_heap_dump_writer.h', + 'trace_event/heap_profiler_stack_frame_deduplicator.cc', + 'trace_event/heap_profiler_stack_frame_deduplicator.h', 'trace_event/java_heap_dump_provider_android.cc', 'trace_event/java_heap_dump_provider_android.h', 'trace_event/memory_allocator_dump.cc', @@ -18,14 +30,6 @@ 'trace_event/memory_dump_request_args.h', 'trace_event/memory_dump_session_state.cc', 'trace_event/memory_dump_session_state.h', - 'trace_event/memory_profiler_allocation_context.cc', - 'trace_event/memory_profiler_allocation_context.h', - 'trace_event/memory_profiler_allocation_register.cc', - 'trace_event/memory_profiler_allocation_register_posix.cc', - 'trace_event/memory_profiler_allocation_register_win.cc', - 'trace_event/memory_profiler_allocation_register.h', - 'trace_event/memory_profiler_heap_dump_writer.cc', - 'trace_event/memory_profiler_heap_dump_writer.h', 'trace_event/process_memory_dump.cc', 'trace_event/process_memory_dump.h', 'trace_event/process_memory_maps.cc', @@ -64,11 +68,12 @@ 'trace_event/winheap_dump_provider_win.h', ], 'trace_event_test_sources' : [ + 'trace_event/heap_profiler_allocation_context_tracker_unittest.cc', + 'trace_event/heap_profiler_allocation_register_unittest.cc', + 'trace_event/heap_profiler_stack_frame_deduplicator_unittest.cc', 'trace_event/java_heap_dump_provider_android_unittest.cc', 'trace_event/memory_allocator_dump_unittest.cc', 'trace_event/memory_dump_manager_unittest.cc', - 'trace_event/memory_profiler_allocation_context_unittest.cc', - 'trace_event/memory_profiler_allocation_register_unittest.cc', 'trace_event/process_memory_dump_unittest.cc', 'trace_event/process_memory_totals_dump_provider_unittest.cc', 'trace_event/trace_config_memory_test_util.h',
diff --git a/base/trace_event/trace_log.cc b/base/trace_event/trace_log.cc index d9a7e3b..31dda00a 100644 --- a/base/trace_event/trace_log.cc +++ b/base/trace_event/trace_log.cc
@@ -26,9 +26,9 @@ #include "base/threading/thread_id_name_manager.h" #include "base/threading/worker_pool.h" #include "base/time/time.h" +#include "base/trace_event/heap_profiler_allocation_context_tracker.h" #include "base/trace_event/memory_dump_manager.h" #include "base/trace_event/memory_dump_provider.h" -#include "base/trace_event/memory_profiler_allocation_context.h" #include "base/trace_event/process_memory_dump.h" #include "base/trace_event/trace_buffer.h" #include "base/trace_event/trace_event.h"
diff --git a/build/common.gypi b/build/common.gypi index 9f2f91ad..df6ba204 100644 --- a/build/common.gypi +++ b/build/common.gypi
@@ -1987,6 +1987,13 @@ ['asan==1 or syzyasan==1', { 'win_use_allocator_shim%': 0, }], + # The AddressSanitizer build should be a console program as it prints + # out stuff on stderr. + ['asan==1', { + 'win_console_app%': 1, + }, { + 'win_console_app%': 0, + }], ['syzyasan==1', { 'kasko%': 1, }],
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn index 104001af..ab96da61 100644 --- a/chrome/BUILD.gn +++ b/chrome/BUILD.gn
@@ -11,6 +11,14 @@ import("//chrome/chrome_repack_locales.gni") import("//chrome/version.gni") +declare_args() { + # If true, builds as a console app (rather than a windowed app), which allows + # logging to be printed to the user. This will cause a terminal window to pop + # up when Chrome is not run from the command line, so should only be used for + # development. Only has an effect on Windows builds. + win_console_app = false +} + if (is_android) { import("//build/config/android/rules.gni") } @@ -40,6 +48,12 @@ ":chrome_initial", ] } + + # The AddressSanitizer build should be a console program as it prints out + # stuff on stderr. + if (is_asan) { + win_console_app = true + } } if (!is_android) { @@ -154,9 +168,11 @@ "wintrust.lib", "crypt32.lib", ] - if (!is_asan) { - # Set /SUBSYSTEM:WINDOWS for chrome.exe itself, except for the - # AddressSanitizer build where console output is important. + if (win_console_app) { + defines += [ "WIN_CONSOLE_APP" ] + } else { + # Set /SUBSYSTEM:WINDOWS for chrome.exe itself, unless a console build + # has been requested. configs -= [ "//build/config/win:console" ] configs += [ "//build/config/win:windowed" ] }
diff --git a/chrome/VERSION b/chrome/VERSION index 50c1ed06..260ff22 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=49 MINOR=0 -BUILD=2565 +BUILD=2566 PATCH=0
diff --git a/chrome/app/chrome_exe_main_win.cc b/chrome/app/chrome_exe_main_win.cc index a5f8ee1..e3e1754 100644 --- a/chrome/app/chrome_exe_main_win.cc +++ b/chrome/app/chrome_exe_main_win.cc
@@ -123,11 +123,9 @@ } // namespace -#if !defined(ADDRESS_SANITIZER) +#if !defined(WIN_CONSOLE_APP) int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE prev, wchar_t*, int) { #else -// The AddressSanitizer build should be a console program as it prints out stuff -// on stderr. int main() { HINSTANCE instance = GetModuleHandle(NULL); #endif
diff --git a/chrome/browser/android/password_ui_view_android.cc b/chrome/browser/android/password_ui_view_android.cc index 22fe77aa..37e7d34 100644 --- a/chrome/browser/android/password_ui_view_android.cc +++ b/chrome/browser/android/password_ui_view_android.cc
@@ -45,7 +45,7 @@ } void PasswordUIViewAndroid::SetPasswordList( - const ScopedVector<autofill::PasswordForm>& password_list, + const std::vector<scoped_ptr<autofill::PasswordForm>>& password_list, bool show_passwords) { // Android just ignores the |show_passwords| argument. JNIEnv* env = base::android::AttachCurrentThread(); @@ -57,7 +57,8 @@ } void PasswordUIViewAndroid::SetPasswordExceptionList( - const ScopedVector<autofill::PasswordForm>& password_exception_list) { + const std::vector<scoped_ptr<autofill::PasswordForm>>& + password_exception_list) { JNIEnv* env = base::android::AttachCurrentThread(); ScopedJavaLocalRef<jobject> ui_controller = weak_java_ui_controller_.get(env); if (!ui_controller.is_null()) {
diff --git a/chrome/browser/android/password_ui_view_android.h b/chrome/browser/android/password_ui_view_android.h index 50fed628..ffbd2ee 100644 --- a/chrome/browser/android/password_ui_view_android.h +++ b/chrome/browser/android/password_ui_view_android.h
@@ -31,10 +31,11 @@ const std::string& username, const base::string16& password_value) override; void SetPasswordList( - const ScopedVector<autofill::PasswordForm>& password_list, + const std::vector<scoped_ptr<autofill::PasswordForm>>& password_list, bool show_passwords) override; - void SetPasswordExceptionList(const ScopedVector<autofill::PasswordForm>& - password_exception_list) override; + void SetPasswordExceptionList( + const std::vector<scoped_ptr<autofill::PasswordForm>>& + password_exception_list) override; // Calls from Java. base::android::ScopedJavaLocalRef<jobject> GetSavedPasswordEntry(
diff --git a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc index d786adb..3f15d3b 100644 --- a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc +++ b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc
@@ -148,7 +148,7 @@ } void PasswordsPrivateDelegateImpl::SetPasswordList( - const ScopedVector<autofill::PasswordForm>& password_list, + const std::vector<scoped_ptr<autofill::PasswordForm>>& password_list, bool show_passwords) { // Rebuild |login_pair_to_index_map_| so that it reflects the contents of the // new list. @@ -162,7 +162,7 @@ // Now, create a list of PasswordUiEntry objects to send to observers. current_entries_.clear(); - for (const autofill::PasswordForm* form : password_list) { + for (const auto& form : password_list) { linked_ptr<api::passwords_private::PasswordUiEntry> entry( new api::passwords_private::PasswordUiEntry); entry->login_pair.origin_url = @@ -192,7 +192,8 @@ } void PasswordsPrivateDelegateImpl::SetPasswordExceptionList( - const ScopedVector<autofill::PasswordForm>& password_exception_list) { + const std::vector<scoped_ptr<autofill::PasswordForm>>& + password_exception_list) { // Rebuild |exception_url_to_index_map_| so that it reflects the contents of // the new list. exception_url_to_index_map_.clear(); @@ -204,7 +205,7 @@ // Now, create a list of exceptions to send to observers. current_exceptions_.clear(); - for (const autofill::PasswordForm* form : password_exception_list) { + for (const auto& form : password_exception_list) { current_exceptions_.push_back( password_manager::GetHumanReadableOrigin(*form, languages_)); }
diff --git a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.h b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.h index 63207cb..a3aa82b 100644 --- a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.h +++ b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.h
@@ -53,10 +53,11 @@ const std::string& username, const base::string16& plaintext_password) override; void SetPasswordList( - const ScopedVector<autofill::PasswordForm>& password_list, + const std::vector<scoped_ptr<autofill::PasswordForm>>& password_list, bool show_passwords) override; - void SetPasswordExceptionList(const ScopedVector<autofill::PasswordForm>& - password_exception_list) override; + void SetPasswordExceptionList( + const std::vector<scoped_ptr<autofill::PasswordForm>>& + password_exception_list) override; #if !defined(OS_ANDROID) gfx::NativeWindow GetNativeWindow() const override; #endif
diff --git a/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.css b/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.css index e4ec546..1133812 100644 --- a/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.css +++ b/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.css
@@ -17,6 +17,16 @@ color: rgb(20, 20, 20); } +paper-ripple { + /* Allowing the ripple to capture pointer events prevents a focus rectangle + * for showing up for clicks, while still allowing it with tab-navigation. + * This undoes a paper-ripple bugfix aimed at non-Chrome browsers. + * TODO(tsergeant): Improve focus in viewer-bookmark so this can be removed + * (https://crbug.com/5448190). + */ + pointer-events: auto; +} + #title { overflow: hidden; text-overflow: ellipsis;
diff --git a/chrome/browser/ui/passwords/password_manager_presenter.cc b/chrome/browser/ui/passwords/password_manager_presenter.cc index 5769971..914a7a7 100644 --- a/chrome/browser/ui/passwords/password_manager_presenter.cc +++ b/chrome/browser/ui/passwords/password_manager_presenter.cc
@@ -23,6 +23,7 @@ #include "components/autofill/core/common/password_form.h" #include "components/browser_sync/browser/profile_sync_service.h" #include "components/password_manager/core/browser/affiliation_utils.h" +#include "components/password_manager/core/browser/password_manager_util.h" #include "components/password_manager/core/common/password_manager_pref_names.h" #include "components/password_manager/sync/browser/password_sync_util.h" #include "content/public/browser/user_metrics.h" @@ -186,7 +187,7 @@ NOTREACHED(); return NULL; } - return password_list_[index]; + return password_list_[index].get(); } const autofill::PasswordForm* PasswordManagerPresenter::GetPasswordException( @@ -197,7 +198,7 @@ NOTREACHED(); return NULL; } - return password_exception_list_[index]; + return password_exception_list_[index].get(); } void PasswordManagerPresenter::SetPasswordList() { @@ -240,7 +241,8 @@ void PasswordManagerPresenter::PasswordListPopulater::OnGetPasswordStoreResults( ScopedVector<autofill::PasswordForm> results) { - page_->password_list_.swap(results); + page_->password_list_ = + password_manager_util::ConvertScopedVector(results.Pass()); page_->SetPasswordList(); } @@ -261,6 +263,7 @@ void PasswordManagerPresenter::PasswordExceptionListPopulater:: OnGetPasswordStoreResults(ScopedVector<autofill::PasswordForm> results) { - page_->password_exception_list_.swap(results); + page_->password_exception_list_ = + password_manager_util::ConvertScopedVector(results.Pass()); page_->SetPasswordExceptionList(); }
diff --git a/chrome/browser/ui/passwords/password_manager_presenter.h b/chrome/browser/ui/passwords/password_manager_presenter.h index fcb3b696..fce6210 100644 --- a/chrome/browser/ui/passwords/password_manager_presenter.h +++ b/chrome/browser/ui/passwords/password_manager_presenter.h
@@ -8,6 +8,7 @@ #include <string> #include <vector> +#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_vector.h" #include "base/prefs/pref_member.h" #include "components/password_manager/core/browser/password_store.h" @@ -111,8 +112,8 @@ PasswordListPopulater populater_; PasswordExceptionListPopulater exception_populater_; - ScopedVector<autofill::PasswordForm> password_list_; - ScopedVector<autofill::PasswordForm> password_exception_list_; + std::vector<scoped_ptr<autofill::PasswordForm>> password_list_; + std::vector<scoped_ptr<autofill::PasswordForm>> password_exception_list_; // Whether to show stored passwords or not. BooleanPrefMember show_passwords_;
diff --git a/chrome/browser/ui/passwords/password_manager_presenter_unittest.cc b/chrome/browser/ui/passwords/password_manager_presenter_unittest.cc index 8d2417c..a2ebe32 100644 --- a/chrome/browser/ui/passwords/password_manager_presenter_unittest.cc +++ b/chrome/browser/ui/passwords/password_manager_presenter_unittest.cc
@@ -31,9 +31,10 @@ MOCK_METHOD4(ShowPassword, void( size_t, const std::string&, const std::string&, const base::string16&)); MOCK_METHOD2(SetPasswordList, - void(const ScopedVector<autofill::PasswordForm>&, bool)); + void(const std::vector<scoped_ptr<autofill::PasswordForm>>&, + bool)); MOCK_METHOD1(SetPasswordExceptionList, - void(const ScopedVector<autofill::PasswordForm>&)); + void(const std::vector<scoped_ptr<autofill::PasswordForm>>&)); PasswordManagerPresenter* GetPasswordManagerPresenter() { return &password_manager_presenter_; } @@ -81,21 +82,21 @@ const GURL& origin, const std::string& user_name, const std::string& password) { - autofill::PasswordForm* form = new autofill::PasswordForm(); + scoped_ptr<autofill::PasswordForm> form(new autofill::PasswordForm()); form->origin = origin; form->username_element = base::ASCIIToUTF16("Email"); form->username_value = base::ASCIIToUTF16(user_name); form->password_element = base::ASCIIToUTF16("Passwd"); form->password_value = base::ASCIIToUTF16(password); - mock_controller_->GetPasswordManagerPresenter()->password_list_ - .push_back(form); + mock_controller_->GetPasswordManagerPresenter()->password_list_.push_back( + form.Pass()); } void PasswordManagerPresenterTest::AddPasswordException(const GURL& origin) { - autofill::PasswordForm* form = new autofill::PasswordForm(); + scoped_ptr<autofill::PasswordForm> form(new autofill::PasswordForm()); form->origin = origin; - mock_controller_->GetPasswordManagerPresenter()->password_exception_list_ - .push_back(form); + mock_controller_->GetPasswordManagerPresenter() + ->password_exception_list_.push_back(form.Pass()); } void PasswordManagerPresenterTest::UpdateLists() { @@ -109,44 +110,52 @@ EXPECT_CALL( *GetUIController(), SetPasswordList( - Property(&ScopedVector<autofill::PasswordForm>::size, Eq(0u)), + Property(&std::vector<scoped_ptr<autofill::PasswordForm>>::size, + Eq(0u)), testing::_)); - EXPECT_CALL(*GetUIController(), - SetPasswordExceptionList(Property( - &ScopedVector<autofill::PasswordForm>::size, Eq(0u)))); + EXPECT_CALL( + *GetUIController(), + SetPasswordExceptionList(Property( + &std::vector<scoped_ptr<autofill::PasswordForm>>::size, Eq(0u)))); UpdateLists(); GURL pass_origin("http://abc1.com"); AddPasswordEntry(pass_origin, "test@gmail.com", "test"); EXPECT_CALL( *GetUIController(), SetPasswordList( - Property(&ScopedVector<autofill::PasswordForm>::size, Eq(1u)), + Property(&std::vector<scoped_ptr<autofill::PasswordForm>>::size, + Eq(1u)), testing::_)); - EXPECT_CALL(*GetUIController(), - SetPasswordExceptionList(Property( - &ScopedVector<autofill::PasswordForm>::size, Eq(0u)))); + EXPECT_CALL( + *GetUIController(), + SetPasswordExceptionList(Property( + &std::vector<scoped_ptr<autofill::PasswordForm>>::size, Eq(0u)))); UpdateLists(); GURL except_origin("http://abc2.com"); AddPasswordException(except_origin); EXPECT_CALL( *GetUIController(), SetPasswordList( - Property(&ScopedVector<autofill::PasswordForm>::size, Eq(1u)), + Property(&std::vector<scoped_ptr<autofill::PasswordForm>>::size, + Eq(1u)), testing::_)); - EXPECT_CALL(*GetUIController(), - SetPasswordExceptionList(Property( - &ScopedVector<autofill::PasswordForm>::size, Eq(1u)))); + EXPECT_CALL( + *GetUIController(), + SetPasswordExceptionList(Property( + &std::vector<scoped_ptr<autofill::PasswordForm>>::size, Eq(1u)))); UpdateLists(); GURL pass_origin2("http://example.com"); AddPasswordEntry(pass_origin2, "test@gmail.com", "test"); EXPECT_CALL( *GetUIController(), SetPasswordList( - Property(&ScopedVector<autofill::PasswordForm>::size, Eq(2u)), + Property(&std::vector<scoped_ptr<autofill::PasswordForm>>::size, + Eq(2u)), testing::_)); - EXPECT_CALL(*GetUIController(), - SetPasswordExceptionList(Property( - &ScopedVector<autofill::PasswordForm>::size, Eq(1u)))); + EXPECT_CALL( + *GetUIController(), + SetPasswordExceptionList(Property( + &std::vector<scoped_ptr<autofill::PasswordForm>>::size, Eq(1u)))); UpdateLists(); }
diff --git a/chrome/browser/ui/passwords/password_ui_view.h b/chrome/browser/ui/passwords/password_ui_view.h index 92f1b2c..4299cfa 100644 --- a/chrome/browser/ui/passwords/password_ui_view.h +++ b/chrome/browser/ui/passwords/password_ui_view.h
@@ -6,8 +6,9 @@ #define CHROME_BROWSER_UI_PASSWORDS_PASSWORD_UI_VIEW_H_ #include <string> +#include <vector> -#include "base/memory/scoped_vector.h" +#include "base/memory/scoped_ptr.h" #include "ui/gfx/native_widget_types.h" namespace autofill { @@ -41,13 +42,14 @@ // |password_list| the list of saved password entries. // |show_passwords| true if the passwords should be shown in the UI. virtual void SetPasswordList( - const ScopedVector<autofill::PasswordForm>& password_list, + const std::vector<scoped_ptr<autofill::PasswordForm>>& password_list, bool show_passwords) = 0; // Updates the list of password exceptions in the UI. // |password_exception_list| The list of saved password exceptions. virtual void SetPasswordExceptionList( - const ScopedVector<autofill::PasswordForm>& password_exception_list) = 0; + const std::vector<scoped_ptr<autofill::PasswordForm>>& + password_exception_list) = 0; #if !defined(OS_ANDROID) // Returns the top level NativeWindow for the view. virtual gfx::NativeWindow GetNativeWindow() const = 0;
diff --git a/chrome/browser/ui/webui/gcm_internals_ui.cc b/chrome/browser/ui/webui/gcm_internals_ui.cc index 79e45e8..0529985b 100644 --- a/chrome/browser/ui/webui/gcm_internals_ui.cc +++ b/chrome/browser/ui/webui/gcm_internals_ui.cc
@@ -8,11 +8,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" -#include "base/format_macros.h" #include "base/memory/weak_ptr.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_util.h" -#include "base/strings/stringprintf.h" #include "base/values.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/services/gcm/gcm_profile_service_factory.h" @@ -20,6 +16,7 @@ #include "components/gcm_driver/gcm_client.h" #include "components/gcm_driver/gcm_driver.h" #include "components/gcm_driver/gcm_internals_constants.h" +#include "components/gcm_driver/gcm_internals_helper.h" #include "components/gcm_driver/gcm_profile_service.h" #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_controller.h" @@ -29,85 +26,6 @@ namespace { -void SetCheckinInfo( - const std::vector<gcm::CheckinActivity>& checkins, - base::ListValue* checkin_info) { - std::vector<gcm::CheckinActivity>::const_iterator it = checkins.begin(); - for (; it < checkins.end(); ++it) { - base::ListValue* row = new base::ListValue(); - checkin_info->Append(row); - - row->AppendDouble(it->time.ToJsTime()); - row->AppendString(it->event); - row->AppendString(it->details); - } -} - -void SetConnectionInfo( - const std::vector<gcm::ConnectionActivity>& connections, - base::ListValue* connection_info) { - std::vector<gcm::ConnectionActivity>::const_iterator it = connections.begin(); - for (; it < connections.end(); ++it) { - base::ListValue* row = new base::ListValue(); - connection_info->Append(row); - - row->AppendDouble(it->time.ToJsTime()); - row->AppendString(it->event); - row->AppendString(it->details); - } -} - -void SetRegistrationInfo( - const std::vector<gcm::RegistrationActivity>& registrations, - base::ListValue* registration_info) { - std::vector<gcm::RegistrationActivity>::const_iterator it = - registrations.begin(); - for (; it < registrations.end(); ++it) { - base::ListValue* row = new base::ListValue(); - registration_info->Append(row); - - row->AppendDouble(it->time.ToJsTime()); - row->AppendString(it->app_id); - row->AppendString(it->source); - row->AppendString(it->event); - row->AppendString(it->details); - } -} - -void SetReceivingInfo( - const std::vector<gcm::ReceivingActivity>& receives, - base::ListValue* receive_info) { - std::vector<gcm::ReceivingActivity>::const_iterator it = receives.begin(); - for (; it < receives.end(); ++it) { - base::ListValue* row = new base::ListValue(); - receive_info->Append(row); - - row->AppendDouble(it->time.ToJsTime()); - row->AppendString(it->app_id); - row->AppendString(it->from); - row->AppendString(base::IntToString(it->message_byte_size)); - row->AppendString(it->event); - row->AppendString(it->details); - } -} - -void SetSendingInfo( - const std::vector<gcm::SendingActivity>& sends, - base::ListValue* send_info) { - std::vector<gcm::SendingActivity>::const_iterator it = sends.begin(); - for (; it < sends.end(); ++it) { - base::ListValue* row = new base::ListValue(); - send_info->Append(row); - - row->AppendDouble(it->time.ToJsTime()); - row->AppendString(it->app_id); - row->AppendString(it->receiver_id); - row->AppendString(it->message_id); - row->AppendString(it->event); - row->AppendString(it->details); - } -} - // Class acting as a controller of the chrome://gcm-internals WebUI. class GcmInternalsUIMessageHandler : public content::WebUIMessageHandler { public: @@ -150,66 +68,8 @@ gcm::GCMProfileService* profile_service, const gcm::GCMClient::GCMStatistics* stats) const { base::DictionaryValue results; - base::DictionaryValue* device_info = new base::DictionaryValue(); - results.Set(gcm_driver::kDeviceInfo, device_info); - - device_info->SetBoolean(gcm_driver::kProfileServiceCreated, - profile_service != NULL); - device_info->SetBoolean( - gcm_driver::kGcmEnabled, - gcm::GCMProfileService::IsGCMEnabled(profile->GetPrefs())); - if (stats) { - results.SetBoolean(gcm_driver::kIsRecording, stats->is_recording); - device_info->SetBoolean(gcm_driver::kGcmClientCreated, - stats->gcm_client_created); - device_info->SetString(gcm_driver::kGcmClientState, - stats->gcm_client_state); - device_info->SetBoolean(gcm_driver::kConnectionClientCreated, - stats->connection_client_created); - device_info->SetString(gcm_driver::kRegisteredAppIds, - base::JoinString(stats->registered_app_ids, ",")); - if (stats->connection_client_created) - device_info->SetString(gcm_driver::kConnectionState, - stats->connection_state); - if (stats->android_id > 0) { - device_info->SetString( - gcm_driver::kAndroidId, - base::StringPrintf("0x%" PRIx64, stats->android_id)); - } - device_info->SetInteger(gcm_driver::kSendQueueSize, stats->send_queue_size); - device_info->SetInteger(gcm_driver::kResendQueueSize, - stats->resend_queue_size); - - if (stats->recorded_activities.checkin_activities.size() > 0) { - base::ListValue* checkin_info = new base::ListValue(); - results.Set(gcm_driver::kCheckinInfo, checkin_info); - SetCheckinInfo(stats->recorded_activities.checkin_activities, - checkin_info); - } - if (stats->recorded_activities.connection_activities.size() > 0) { - base::ListValue* connection_info = new base::ListValue(); - results.Set(gcm_driver::kConnectionInfo, connection_info); - SetConnectionInfo(stats->recorded_activities.connection_activities, - connection_info); - } - if (stats->recorded_activities.registration_activities.size() > 0) { - base::ListValue* registration_info = new base::ListValue(); - results.Set(gcm_driver::kRegistrationInfo, registration_info); - SetRegistrationInfo(stats->recorded_activities.registration_activities, - registration_info); - } - if (stats->recorded_activities.receiving_activities.size() > 0) { - base::ListValue* receive_info = new base::ListValue(); - results.Set(gcm_driver::kReceiveInfo, receive_info); - SetReceivingInfo(stats->recorded_activities.receiving_activities, - receive_info); - } - if (stats->recorded_activities.sending_activities.size() > 0) { - base::ListValue* send_info = new base::ListValue(); - results.Set(gcm_driver::kSendInfo, send_info); - SetSendingInfo(stats->recorded_activities.sending_activities, send_info); - } - } + gcm_driver::SetGCMInternalsInfo(stats, profile_service, profile->GetPrefs(), + &results); web_ui()->CallJavascriptFunction(gcm_driver::kSetGcmInternalsInfo, results); }
diff --git a/chrome/browser/ui/webui/options/password_manager_handler.cc b/chrome/browser/ui/webui/options/password_manager_handler.cc index 216a008..23055dd 100644 --- a/chrome/browser/ui/webui/options/password_manager_handler.cc +++ b/chrome/browser/ui/webui/options/password_manager_handler.cc
@@ -216,12 +216,12 @@ } void PasswordManagerHandler::SetPasswordList( - const ScopedVector<autofill::PasswordForm>& password_list, + const std::vector<scoped_ptr<autofill::PasswordForm>>& password_list, bool show_passwords) { base::ListValue entries; languages_ = GetProfile()->GetPrefs()->GetString(prefs::kAcceptLanguages); base::string16 placeholder(base::ASCIIToUTF16(" ")); - for (const autofill::PasswordForm* saved_password : password_list) { + for (const auto& saved_password : password_list) { scoped_ptr<base::DictionaryValue> entry(new base::DictionaryValue); CopyOriginInfoOfPasswordForm(*saved_password, languages_, entry.get()); @@ -250,9 +250,10 @@ } void PasswordManagerHandler::SetPasswordExceptionList( - const ScopedVector<autofill::PasswordForm>& password_exception_list) { + const std::vector<scoped_ptr<autofill::PasswordForm>>& + password_exception_list) { base::ListValue entries; - for (const autofill::PasswordForm* exception : password_exception_list) { + for (const auto& exception : password_exception_list) { scoped_ptr<base::DictionaryValue> entry(new base::DictionaryValue); CopyOriginInfoOfPasswordForm(*exception, languages_, entry.get()); entries.Append(entry.release());
diff --git a/chrome/browser/ui/webui/options/password_manager_handler.h b/chrome/browser/ui/webui/options/password_manager_handler.h index a08ecbe2..5befa1b 100644 --- a/chrome/browser/ui/webui/options/password_manager_handler.h +++ b/chrome/browser/ui/webui/options/password_manager_handler.h
@@ -35,10 +35,11 @@ const std::string& username, const base::string16& password_value) override; void SetPasswordList( - const ScopedVector<autofill::PasswordForm>& password_list, + const std::vector<scoped_ptr<autofill::PasswordForm>>& password_list, bool show_passwords) override; - void SetPasswordExceptionList(const ScopedVector<autofill::PasswordForm>& - password_exception_list) override; + void SetPasswordExceptionList( + const std::vector<scoped_ptr<autofill::PasswordForm>>& + password_exception_list) override; #if !defined(OS_ANDROID) gfx::NativeWindow GetNativeWindow() const override; #endif
diff --git a/chrome/chrome_exe.gypi b/chrome/chrome_exe.gypi index a107569..d02673f 100644 --- a/chrome/chrome_exe.gypi +++ b/chrome/chrome_exe.gypi
@@ -109,6 +109,9 @@ 'kasko_dll', ], }], + ['win_console_app==1', { + 'defines': ['WIN_CONSOLE_APP'], + }], ], }], ['OS == "android"', { @@ -450,9 +453,9 @@ 'crypt32.lib' ], 'conditions': [ - ['asan==0', { - # Set /SUBSYSTEM:WINDOWS for chrome.exe itself, except for the - # AddressSanitizer build where console output is important. + ['win_console_app==0', { + # Set /SUBSYSTEM:WINDOWS for chrome.exe itself, unless a + # console build has been requested. 'SubSystem': '2', }], ],
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index f6d85d7..97b4b93 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -7633.0.0 \ No newline at end of file +7644.0.0 \ No newline at end of file
diff --git a/components/drive/search_metadata.cc b/components/drive/search_metadata.cc index fcc3531..1e316f0 100644 --- a/components/drive/search_metadata.cc +++ b/components/drive/search_metadata.cc
@@ -54,44 +54,15 @@ } struct ResultCandidateComparator { - bool operator()(const ResultCandidate* a, const ResultCandidate* b) const { + bool operator()(const scoped_ptr<ResultCandidate>& a, + const scoped_ptr<ResultCandidate>& b) const { return CompareByTimestamp(a->entry, b->entry); } }; -// A wrapper of std::priority_queue which deals with pointers of values. -template<typename T, typename Compare> -class ScopedPriorityQueue { - public: - ScopedPriorityQueue() {} - - ~ScopedPriorityQueue() { - while (!empty()) - pop(); - } - - bool empty() const { return queue_.empty(); } - - size_t size() const { return queue_.size(); } - - const T* top() const { return queue_.top(); } - - void push(T* x) { queue_.push(x); } - - void pop() { - // Keep top alive for the pop() call so that debug checks can access - // underlying data (e.g. validating heap property of the priority queue - // will call the comparator). - T* saved_top = queue_.top(); - queue_.pop(); - delete saved_top; - } - - private: - std::priority_queue<T*, std::vector<T*>, Compare> queue_; - - DISALLOW_COPY_AND_ASSIGN(ScopedPriorityQueue); -}; +typedef std::priority_queue<scoped_ptr<ResultCandidate>, + std::vector<scoped_ptr<ResultCandidate>>, + ResultCandidateComparator> ResultCandidateQueue; // Classifies the given entry as hidden if it's not under specific directories. class HiddenEntryClassifier { @@ -154,8 +125,7 @@ const SearchMetadataPredicate& predicate, size_t at_most_num_matches, HiddenEntryClassifier* hidden_entry_classifier, - ScopedPriorityQueue<ResultCandidate, ResultCandidateComparator>* - result_candidates) { + ResultCandidateQueue* result_candidates) { DCHECK_GE(at_most_num_matches, result_candidates->size()); const ResourceEntry& entry = it->GetValue(); @@ -184,7 +154,8 @@ // Make space for |entry| when appropriate. if (result_candidates->size() == at_most_num_matches) result_candidates->pop(); - result_candidates->push(new ResultCandidate(it->GetID(), entry, highlighted)); + result_candidates->push(make_scoped_ptr( + new ResultCandidate(it->GetID(), entry, highlighted))); return FILE_ERROR_OK; } @@ -194,8 +165,7 @@ const SearchMetadataPredicate& predicate, int at_most_num_matches, MetadataSearchResultVector* results) { - ScopedPriorityQueue<ResultCandidate, - ResultCandidateComparator> result_candidates; + ResultCandidateQueue result_candidates; // Prepare data structure for searching. std::vector<base::string16> keywords =
diff --git a/components/gcm_driver.gypi b/components/gcm_driver.gypi index 7ac49c9..9c5bb23d 100644 --- a/components/gcm_driver.gypi +++ b/components/gcm_driver.gypi
@@ -81,6 +81,8 @@ 'gcm_driver/gcm_driver_desktop.h', 'gcm_driver/gcm_internals_constants.cc', 'gcm_driver/gcm_internals_constants.h', + 'gcm_driver/gcm_internals_helper.cc', + 'gcm_driver/gcm_internals_helper.h', 'gcm_driver/gcm_profile_service.cc', 'gcm_driver/gcm_profile_service.h', 'gcm_driver/gcm_stats_recorder_impl.cc',
diff --git a/components/gcm_driver/BUILD.gn b/components/gcm_driver/BUILD.gn index 2e852433..46c35eb 100644 --- a/components/gcm_driver/BUILD.gn +++ b/components/gcm_driver/BUILD.gn
@@ -45,6 +45,8 @@ "gcm_driver_desktop.h", "gcm_internals_constants.cc", "gcm_internals_constants.h", + "gcm_internals_helper.cc", + "gcm_internals_helper.h", "gcm_profile_service.cc", "gcm_profile_service.h", "gcm_stats_recorder_impl.cc",
diff --git a/components/gcm_driver/gcm_internals_helper.cc b/components/gcm_driver/gcm_internals_helper.cc new file mode 100644 index 0000000..c66d3d7 --- /dev/null +++ b/components/gcm_driver/gcm_internals_helper.cc
@@ -0,0 +1,150 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/gcm_driver/gcm_internals_helper.h" + +#include "base/format_macros.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" +#include "base/values.h" +#include "components/gcm_driver/gcm_activity.h" +#include "components/gcm_driver/gcm_internals_constants.h" +#include "components/gcm_driver/gcm_profile_service.h" + +namespace gcm_driver { + +namespace { + +void SetCheckinInfo(const std::vector<gcm::CheckinActivity>& checkins, + base::ListValue* checkin_info) { + for (const gcm::CheckinActivity& checkin : checkins) { + base::ListValue* row = new base::ListValue(); + checkin_info->Append(row); + + row->AppendDouble(checkin.time.ToJsTime()); + row->AppendString(checkin.event); + row->AppendString(checkin.details); + } +} + +void SetConnectionInfo(const std::vector<gcm::ConnectionActivity>& connections, + base::ListValue* connection_info) { + for (const gcm::ConnectionActivity& connection : connections) { + base::ListValue* row = new base::ListValue(); + connection_info->Append(row); + + row->AppendDouble(connection.time.ToJsTime()); + row->AppendString(connection.event); + row->AppendString(connection.details); + } +} + +void SetRegistrationInfo( + const std::vector<gcm::RegistrationActivity>& registrations, + base::ListValue* registration_info) { + for (const gcm::RegistrationActivity& registration : registrations) { + base::ListValue* row = new base::ListValue(); + registration_info->Append(row); + + row->AppendDouble(registration.time.ToJsTime()); + row->AppendString(registration.app_id); + row->AppendString(registration.source); + row->AppendString(registration.event); + row->AppendString(registration.details); + } +} + +void SetReceivingInfo(const std::vector<gcm::ReceivingActivity>& receives, + base::ListValue* receive_info) { + for (const gcm::ReceivingActivity& receive : receives) { + base::ListValue* row = new base::ListValue(); + receive_info->Append(row); + + row->AppendDouble(receive.time.ToJsTime()); + row->AppendString(receive.app_id); + row->AppendString(receive.from); + row->AppendString(base::IntToString(receive.message_byte_size)); + row->AppendString(receive.event); + row->AppendString(receive.details); + } +} + +void SetSendingInfo(const std::vector<gcm::SendingActivity>& sends, + base::ListValue* send_info) { + for (const gcm::SendingActivity& send : sends) { + base::ListValue* row = new base::ListValue(); + send_info->Append(row); + + row->AppendDouble(send.time.ToJsTime()); + row->AppendString(send.app_id); + row->AppendString(send.receiver_id); + row->AppendString(send.message_id); + row->AppendString(send.event); + row->AppendString(send.details); + } +} + +} // namespace + +void SetGCMInternalsInfo(const gcm::GCMClient::GCMStatistics* stats, + gcm::GCMProfileService* profile_service, + PrefService* prefs, + base::DictionaryValue* results) { + base::DictionaryValue* device_info = new base::DictionaryValue(); + results->Set(kDeviceInfo, device_info); + + device_info->SetBoolean(kProfileServiceCreated, profile_service != NULL); + device_info->SetBoolean(kGcmEnabled, + gcm::GCMProfileService::IsGCMEnabled(prefs)); + if (stats) { + results->SetBoolean(kIsRecording, stats->is_recording); + device_info->SetBoolean(kGcmClientCreated, stats->gcm_client_created); + device_info->SetString(kGcmClientState, stats->gcm_client_state); + device_info->SetBoolean(kConnectionClientCreated, + stats->connection_client_created); + device_info->SetString(kRegisteredAppIds, + base::JoinString(stats->registered_app_ids, ",")); + if (stats->connection_client_created) + device_info->SetString(kConnectionState, stats->connection_state); + if (stats->android_id > 0) { + device_info->SetString( + kAndroidId, base::StringPrintf("0x%" PRIx64, stats->android_id)); + } + device_info->SetInteger(kSendQueueSize, stats->send_queue_size); + device_info->SetInteger(kResendQueueSize, stats->resend_queue_size); + + if (stats->recorded_activities.checkin_activities.size() > 0) { + base::ListValue* checkin_info = new base::ListValue(); + results->Set(kCheckinInfo, checkin_info); + SetCheckinInfo(stats->recorded_activities.checkin_activities, + checkin_info); + } + if (stats->recorded_activities.connection_activities.size() > 0) { + base::ListValue* connection_info = new base::ListValue(); + results->Set(kConnectionInfo, connection_info); + SetConnectionInfo(stats->recorded_activities.connection_activities, + connection_info); + } + if (stats->recorded_activities.registration_activities.size() > 0) { + base::ListValue* registration_info = new base::ListValue(); + results->Set(kRegistrationInfo, registration_info); + SetRegistrationInfo(stats->recorded_activities.registration_activities, + registration_info); + } + if (stats->recorded_activities.receiving_activities.size() > 0) { + base::ListValue* receive_info = new base::ListValue(); + results->Set(kReceiveInfo, receive_info); + SetReceivingInfo(stats->recorded_activities.receiving_activities, + receive_info); + } + if (stats->recorded_activities.sending_activities.size() > 0) { + base::ListValue* send_info = new base::ListValue(); + results->Set(kSendInfo, send_info); + SetSendingInfo(stats->recorded_activities.sending_activities, send_info); + } + } +} + +} // namespace gcm_driver
diff --git a/components/gcm_driver/gcm_internals_helper.h b/components/gcm_driver/gcm_internals_helper.h new file mode 100644 index 0000000..ee89602 --- /dev/null +++ b/components/gcm_driver/gcm_internals_helper.h
@@ -0,0 +1,32 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_GCM_DRIVER_GCM_INTERNALS_HELPER_H_ +#define COMPONENTS_GCM_DRIVER_GCM_INTERNALS_HELPER_H_ + +#include <vector> + +#include "components/gcm_driver/gcm_client.h" + +class PrefService; + +namespace base { +class DictionaryValue; +} + +namespace gcm { +class GCMProfileService; +} + +namespace gcm_driver { + +// Sets the GCM infos for the gcm-internals WebUI in |results|. +void SetGCMInternalsInfo(const gcm::GCMClient::GCMStatistics* stats, + gcm::GCMProfileService* profile_service, + PrefService* prefs, + base::DictionaryValue* results); + +} // namespace gcm_driver + +#endif // COMPONENTS_GCM_DRIVER_GCM_INTERNALS_HELPER_H_
diff --git a/components/history/core/browser/history_backend_unittest.cc b/components/history/core/browser/history_backend_unittest.cc index 6f911ef..7c8ac3f9 100644 --- a/components/history/core/browser/history_backend_unittest.cc +++ b/components/history/core/browser/history_backend_unittest.cc
@@ -87,7 +87,7 @@ base::Time visit_time; history::RedirectList redirects; - for (const auto& row : rows) { + for (const history::URLRow& row : rows) { observer->OnURLVisited(nullptr, ui::PAGE_TRANSITION_LINK, row, redirects, visit_time); } @@ -3170,7 +3170,7 @@ urls.push_back(GURL("http://cnn.com/us")); urls.push_back(GURL("http://cnn.com/intl")); urls.push_back(GURL("http://dogtopia.com/")); - for (const auto& url : urls) { + for (const GURL& url : urls) { backend_->AddPageVisit(url, base::Time::Now(), 0, ui::PAGE_TRANSITION_LINK, history::SOURCE_BROWSED); } @@ -3185,7 +3185,7 @@ urls.push_back(GURL("http://cnn.com/us")); urls.push_back(GURL("https://cnn.com/intl")); urls.push_back(GURL("http://cnn.com:567/sports")); - for (const auto& url : urls) { + for (const GURL& url : urls) { backend_->AddPageVisit(url, base::Time::Now(), 0, ui::PAGE_TRANSITION_LINK, history::SOURCE_BROWSED); } @@ -3198,7 +3198,7 @@ urls.push_back(GURL("http://www.cnn.com/us")); urls.push_back(GURL("http://cnn.com/intl")); urls.push_back(GURL("http://www.dogtopia.com/")); - for (const auto& url : urls) { + for (const GURL& url : urls) { backend_->AddPageVisit(url, base::Time::Now(), 0, ui::PAGE_TRANSITION_LINK, history::SOURCE_BROWSED); } @@ -3213,7 +3213,7 @@ urls.push_back(GURL("http://cnn.com/us")); urls.push_back(GURL("http://cnn.com/intl")); urls.push_back(GURL("http://dogtopia.com/")); - for (const auto& url : urls) { + for (const GURL& url : urls) { backend_->AddPageVisit(url, base::Time::Now(), 0, ui::PAGE_TRANSITION_LINK, history::SOURCE_BROWSED); } @@ -3234,7 +3234,7 @@ urls.push_back(GURL("http://dogtopia.com/")); urls.push_back(GURL("http://dogtopia.com/webcam")); urls.push_back(GURL("http://www.gardenweb.com/")); - for (const auto& url : urls) { + for (const GURL& url : urls) { backend_->AddPageVisit(url, base::Time::Now(), 0, ui::PAGE_TRANSITION_LINK, history::SOURCE_BROWSED); } @@ -3255,7 +3255,7 @@ urls.push_back(GURL("data:text/plain,Hello%20world%21")); urls.push_back(GURL("chrome://memory")); urls.push_back(GURL("about:mammon")); - for (const auto& url : urls) { + for (const GURL& url : urls) { backend_->AddPageVisit(url, base::Time::Now(), 0, ui::PAGE_TRANSITION_LINK, history::SOURCE_BROWSED); } @@ -3268,7 +3268,7 @@ urls.push_back(GURL("http://cnn.com/us")); urls.push_back(GURL("http://cnn.com/intl")); urls.push_back(GURL("http://dogtopia.com/")); - for (const auto& url : urls) { + for (const GURL& url : urls) { backend_->AddPageVisit(url, base::Time::Now(), 0, ui::PAGE_TRANSITION_LINK, history::SOURCE_BROWSED); } @@ -3292,7 +3292,7 @@ urls.push_back(GURL("http://cnn.com/us")); urls.push_back(GURL("http://cnn.com/intl")); urls.push_back(GURL("http://dogtopia.com/")); - for (const auto& url : urls) { + for (const GURL& url : urls) { backend_->AddPageVisit(url, base::Time::Now(), 0, ui::PAGE_TRANSITION_LINK, history::SOURCE_BROWSED); } @@ -3306,7 +3306,7 @@ urls.clear(); urls.push_back(GURL("http://cnn.com/us")); urls.push_back(GURL("http://www.unipresse.com/")); - for (const auto& url : urls) { + for (const GURL& url : urls) { backend_->AddPageVisit(url, base::Time::Now(), 0, ui::PAGE_TRANSITION_CHAIN_END, history::SOURCE_BROWSED);
diff --git a/components/password_manager/core/browser/password_manager_util.cc b/components/password_manager/core/browser/password_manager_util.cc index 44123a0..1b4bff4 100644 --- a/components/password_manager/core/browser/password_manager_util.cc +++ b/components/password_manager/core/browser/password_manager_util.cc
@@ -74,4 +74,15 @@ android_credentials->swap(result); } +std::vector<scoped_ptr<autofill::PasswordForm>> ConvertScopedVector( + ScopedVector<autofill::PasswordForm> old_vector) { + std::vector<scoped_ptr<autofill::PasswordForm>> new_vector; + new_vector.reserve(old_vector.size()); + for (auto* form : old_vector) { + new_vector.push_back(make_scoped_ptr(form)); + } + old_vector.weak_clear(); // All owned by |new_vector| by now. + return new_vector; +} + } // namespace password_manager_util
diff --git a/components/password_manager/core/browser/password_manager_util.h b/components/password_manager/core/browser/password_manager_util.h index ef2517b..3b00570 100644 --- a/components/password_manager/core/browser/password_manager_util.h +++ b/components/password_manager/core/browser/password_manager_util.h
@@ -5,8 +5,11 @@ #ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_MANAGER_UTIL_H_ #define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_MANAGER_UTIL_H_ +#include <vector> + #include "base/basictypes.h" #include "base/callback.h" +#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_vector.h" #include "components/password_manager/core/browser/password_manager_client.h" #include "ui/gfx/native_widget_types.h" @@ -42,6 +45,11 @@ void TrimUsernameOnlyCredentials( ScopedVector<autofill::PasswordForm>* android_credentials); +// TODO(crbug.com/555132): Remove this when the migration from ScopedVector is +// finished for PasswordForm. +std::vector<scoped_ptr<autofill::PasswordForm>> ConvertScopedVector( + ScopedVector<autofill::PasswordForm> old_vector); + } // namespace password_manager_util #endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_MANAGER_UTIL_H_
diff --git a/content/child/web_memory_dump_provider_adapter.cc b/content/child/web_memory_dump_provider_adapter.cc index 8666fd09..b0a8a6a 100644 --- a/content/child/web_memory_dump_provider_adapter.cc +++ b/content/child/web_memory_dump_provider_adapter.cc
@@ -6,8 +6,10 @@ #include "base/lazy_instance.h" #include "base/synchronization/lock.h" -#include "base/trace_event/memory_profiler_allocation_register.h" -#include "base/trace_event/memory_profiler_heap_dump_writer.h" +#include "base/trace_event/heap_profiler_allocation_context.h" +#include "base/trace_event/heap_profiler_allocation_context_tracker.h" +#include "base/trace_event/heap_profiler_allocation_register.h" +#include "base/trace_event/heap_profiler_heap_dump_writer.h" #include "base/trace_event/process_memory_dump.h" #include "base/trace_event/trace_event_argument.h" #include "base/trace_event/trace_event_memory_overhead.h"
diff --git a/content/renderer/dom_serializer_browsertest.cc b/content/renderer/dom_serializer_browsertest.cc index c7234e82..db37905 100644 --- a/content/renderer/dom_serializer_browsertest.cc +++ b/content/renderer/dom_serializer_browsertest.cc
@@ -54,33 +54,6 @@ namespace content { -// Iterate recursively over sub-frames to find one with with a given url. -WebFrame* FindSubFrameByURL(WebView* web_view, const GURL& url) { - if (!web_view->mainFrame()) - return NULL; - - std::vector<WebFrame*> stack; - stack.push_back(web_view->mainFrame()); - - while (!stack.empty()) { - WebFrame* current_frame = stack.back(); - stack.pop_back(); - if (GURL(current_frame->document().url()) == url) - return current_frame; - WebElementCollection all = current_frame->document().all(); - for (WebElement element = all.firstItem(); - !element.isNull(); element = all.nextItem()) { - // Check frame tag and iframe tag - if (!element.hasHTMLTagName("frame") && !element.hasHTMLTagName("iframe")) - continue; - WebFrame* sub_frame = WebLocalFrame::fromFrameOwnerElement(element); - if (sub_frame) - stack.push_back(sub_frame); - } - } - return NULL; -} - bool HasDocType(const WebDocument& doc) { return !doc.doctype().isNull(); } @@ -199,6 +172,15 @@ return GetWebView()->mainFrame(); } + WebFrame* FindSubFrameByURL(const GURL& url) { + for (WebFrame* frame = GetWebView()->mainFrame(); frame; + frame = frame->traverseNext(false)) { + if (GURL(frame->document().url()) == url) + return frame; + } + return nullptr; + } + // Load web page according to input content and relative URLs within // the document. void LoadContents(const std::string& contents, @@ -229,7 +211,7 @@ // Serialize DOM belonging to a frame with the specified |frame_url|. void SerializeDomForURL(const GURL& frame_url) { // Find corresponding WebFrame according to frame_url. - WebFrame* web_frame = FindSubFrameByURL(GetWebView(), frame_url); + WebFrame* web_frame = FindSubFrameByURL(frame_url); ASSERT_TRUE(web_frame != NULL); WebVector<WebURL> links; links.assign(&frame_url, 1); @@ -248,7 +230,7 @@ void SerializeHTMLDOMWithDocTypeOnRenderer(const GURL& file_url) { // Make sure original contents have document type. - WebFrame* web_frame = FindSubFrameByURL(GetWebView(), file_url); + WebFrame* web_frame = FindSubFrameByURL(file_url); ASSERT_TRUE(web_frame != NULL); WebDocument doc = web_frame->document(); ASSERT_TRUE(HasDocType(doc)); @@ -266,7 +248,7 @@ void SerializeHTMLDOMWithoutDocTypeOnRenderer(const GURL& file_url) { // Make sure original contents do not have document type. - WebFrame* web_frame = FindSubFrameByURL(GetWebView(), file_url); + WebFrame* web_frame = FindSubFrameByURL(file_url); ASSERT_TRUE(web_frame != NULL); WebDocument doc = web_frame->document(); ASSERT_TRUE(!HasDocType(doc)); @@ -312,7 +294,7 @@ void SerializeHTMLDOMWithNoMetaCharsetInOriginalDocOnRenderer( const GURL& file_url) { // Make sure there is no META charset declaration in original document. - WebFrame* web_frame = FindSubFrameByURL(GetWebView(), file_url); + WebFrame* web_frame = FindSubFrameByURL(file_url); ASSERT_TRUE(web_frame != NULL); WebDocument doc = web_frame->document(); ASSERT_TRUE(doc.isHTMLDocument()); @@ -362,7 +344,7 @@ const GURL& file_url) { // Make sure there are multiple META charset declarations in original // document. - WebFrame* web_frame = FindSubFrameByURL(GetWebView(), file_url); + WebFrame* web_frame = FindSubFrameByURL(file_url); ASSERT_TRUE(web_frame != NULL); WebDocument doc = web_frame->document(); ASSERT_TRUE(doc.isHTMLDocument()); @@ -426,7 +408,7 @@ LoadContents(original_contents, file_url, WebString()); // Get BODY's text content in DOM. - WebFrame* web_frame = FindSubFrameByURL(GetWebView(), file_url); + WebFrame* web_frame = FindSubFrameByURL(file_url); ASSERT_TRUE(web_frame != NULL); WebDocument doc = web_frame->document(); ASSERT_TRUE(doc.isHTMLDocument()); @@ -478,7 +460,7 @@ // Load the test contents. LoadContents(original_contents, file_url, WebString()); // Get value of BODY's title attribute in DOM. - WebFrame* web_frame = FindSubFrameByURL(GetWebView(), file_url); + WebFrame* web_frame = FindSubFrameByURL(file_url); ASSERT_TRUE(web_frame != NULL); WebDocument doc = web_frame->document(); ASSERT_TRUE(doc.isHTMLDocument()); @@ -512,7 +494,7 @@ void SerializeHTMLDOMWithNonStandardEntitiesOnRenderer(const GURL& file_url) { // Get value of BODY's title attribute in DOM. - WebFrame* web_frame = FindSubFrameByURL(GetWebView(), file_url); + WebFrame* web_frame = FindSubFrameByURL(file_url); WebDocument doc = web_frame->document(); ASSERT_TRUE(doc.isHTMLDocument()); WebElement body_element = doc.body(); @@ -544,7 +526,7 @@ // Since for this test, we assume there is no savable sub-resource links for // this test file, also all links are relative URLs in this test file, so we // need to check those relative URLs and make sure document has BASE tag. - WebFrame* web_frame = FindSubFrameByURL(GetWebView(), file_url); + WebFrame* web_frame = FindSubFrameByURL(file_url); ASSERT_TRUE(web_frame != NULL); WebDocument doc = web_frame->document(); ASSERT_TRUE(doc.isHTMLDocument()); @@ -678,7 +660,7 @@ void SubResourceForElementsInNonHTMLNamespaceOnRenderer( const GURL& file_url) { - WebFrame* web_frame = FindSubFrameByURL(GetWebView(), file_url); + WebFrame* web_frame = FindSubFrameByURL(file_url); ASSERT_TRUE(web_frame != NULL); WebDocument doc = web_frame->document(); WebNode lastNodeInBody = doc.body().lastChild();
diff --git a/ios/provider/ios_provider_web.gyp b/ios/provider/ios_provider_web.gyp index 90b768761..8d4a10fe 100644 --- a/ios/provider/ios_provider_web.gyp +++ b/ios/provider/ios_provider_web.gyp
@@ -7,6 +7,7 @@ }, 'targets': [ { + # GN version: //ios/public/provider/web 'target_name': 'ios_provider_web', 'type': 'static_library', 'include_dirs': [
diff --git a/ios/public/provider/web/BUILD.gn b/ios/public/provider/web/BUILD.gn new file mode 100644 index 0000000..2df8a62c --- /dev/null +++ b/ios/public/provider/web/BUILD.gn
@@ -0,0 +1,21 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("web") { + sources = [ + "web_controller_provider.h", + "web_controller_provider.mm", + "web_ui_ios.h", + "web_ui_ios_controller.cc", + "web_ui_ios_controller.h", + "web_ui_ios_controller_factory.h", + "web_ui_ios_message_handler.cc", + "web_ui_ios_message_handler.h", + ] + + deps = [ + "//base", + "//ios/web", + ] +}
diff --git a/media/BUILD.gn b/media/BUILD.gn index 1e2589f5..f191317 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn
@@ -658,7 +658,7 @@ "test/data/", ] - # TODO(wolenetz): Fix size_t to int truncation in win64. + # TODO(wolenetz): Fix size_t to int trunctaion in win64. # See http://crbug.com/171009 configs += [ "//build/config/compiler:no_size_t_to_int_warning" ] @@ -695,12 +695,6 @@ ] } - # If ExternalClearKey is built, we can test CdmAdapter. - if (enable_pepper_cdms) { - sources += [ "cdm/cdm_adapter_unittest.cc" ] - deps += [ "//media/cdm/ppapi:clearkeycdm" ] - } - if (media_use_ffmpeg) { sources += [ "ffmpeg/ffmpeg_common_unittest.cc",
diff --git a/media/cdm/aes_decryptor.cc b/media/cdm/aes_decryptor.cc index 1c3f367..8eaa058 100644 --- a/media/cdm/aes_decryptor.cc +++ b/media/cdm/aes_decryptor.cc
@@ -309,8 +309,8 @@ promise->resolve(session_id); // No URL needed for license requests. - GURL empty_gurl; - session_message_cb_.Run(session_id, LICENSE_REQUEST, message, empty_gurl); + session_message_cb_.Run(session_id, LICENSE_REQUEST, message, + GURL::EmptyGURL()); } void AesDecryptor::LoadSession(SessionType session_type,
diff --git a/media/cdm/cdm_adapter_unittest.cc b/media/cdm/cdm_adapter_unittest.cc deleted file mode 100644 index 1b3f12b..0000000 --- a/media/cdm/cdm_adapter_unittest.cc +++ /dev/null
@@ -1,374 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/bind.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/path_service.h" -#include "base/run_loop.h" -#include "base/scoped_native_library.h" -#include "media/base/cdm_callback_promise.h" -#include "media/base/cdm_key_information.h" -#include "media/base/media_keys.h" -#include "media/cdm/api/content_decryption_module.h" -#include "media/cdm/cdm_adapter.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using ::testing::_; -using ::testing::SaveArg; -MATCHER(IsNotEmpty, "") { - return !arg.empty(); -} - -// TODO(jrummell): These tests are a subset of those in aes_decryptor_unittest. -// Refactor aes_decryptor_unittest.cc to handle AesDecryptor directly and -// via CdmAdapter once CdmAdapter supports decrypting functionality. There -// will also be tests that only CdmAdapter supports, like file IO, which -// will need to be handled separately. - -namespace media { - -// INITIALIZE_CDM_MODULE is a macro in api/content_decryption_module.h. -// However, we need to pass it as a string to GetFunctionPointer() once it -// is expanded. -#define STRINGIFY(X) #X -#define MAKE_STRING(X) STRINGIFY(X) - -const char kExternalClearKeyKeySystem[] = "org.chromium.externalclearkey"; - -// File name of the External ClearKey CDM on different platforms. -const base::FilePath::CharType kExternalClearKeyCdmFileName[] = -#if defined(OS_MACOSX) - FILE_PATH_LITERAL("libclearkeycdm.dylib"); -#elif defined(OS_WIN) - FILE_PATH_LITERAL("clearkeycdm.dll"); -#else // OS_LINUX, etc. - FILE_PATH_LITERAL("libclearkeycdm.so"); -#endif - -// Random key ID used to create a session. -const uint8 kKeyId[] = { - // base64 equivalent is AQIDBAUGBwgJCgsMDQ4PEA - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, -}; - -const char kKeyIdAsJWK[] = "{\"kids\": [\"AQIDBAUGBwgJCgsMDQ4PEA\"]}"; - -const uint8 kKeyIdAsPssh[] = { - 0x00, 0x00, 0x00, 0x00, 'p', 's', 's', 'h', // size = 0 - 0x01, // version = 1 - 0x00, 0x00, 0x00, // flags - 0x10, 0x77, 0xEF, 0xEC, 0xC0, 0xB2, 0x4D, 0x02, // Common SystemID - 0xAC, 0xE3, 0x3C, 0x1E, 0x52, 0xE2, 0xFB, 0x4B, - 0x00, 0x00, 0x00, 0x01, // key count - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // key - 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, - 0x00, 0x00, 0x00, 0x00, // datasize -}; - -// Key is 0x0405060708090a0b0c0d0e0f10111213, -// base64 equivalent is BAUGBwgJCgsMDQ4PEBESEw. -const char kKeyAsJWK[] = - "{" - " \"keys\": [" - " {" - " \"kty\": \"oct\"," - " \"alg\": \"A128KW\"," - " \"kid\": \"AQIDBAUGBwgJCgsMDQ4PEA\"," - " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\"" - " }" - " ]," - " \"type\": \"temporary\"" - "}"; - -class CdmAdapterTest : public testing::Test { - public: - enum ExpectedResult { SUCCESS, FAILURE }; - - CdmAdapterTest() {} - ~CdmAdapterTest() override {} - - protected: - // Initializes the adapter. |expected_result| tests that the call succeeds - // or generates an error. - void InitializeAndExpect(base::FilePath library_path, - ExpectedResult expected_result) { - CdmConfig cdm_config; // default settings of false are sufficient. - - CdmAdapter::Create( - kExternalClearKeyKeySystem, library_path, cdm_config, - base::Bind(&CdmAdapterTest::OnSessionMessage, base::Unretained(this)), - base::Bind(&CdmAdapterTest::OnSessionClosed, base::Unretained(this)), - base::Bind(&CdmAdapterTest::OnLegacySessionError, - base::Unretained(this)), - base::Bind(&CdmAdapterTest::OnSessionKeysChange, - base::Unretained(this)), - base::Bind(&CdmAdapterTest::OnSessionExpirationUpdate, - base::Unretained(this)), - base::Bind(&CdmAdapterTest::OnCdmCreated, base::Unretained(this), - expected_result)); - RunUntilIdle(); - } - - // Creates a new session using |key_id|. |session_id_| will be set - // when the promise is resolved. |expected_result| tests that - // CreateSessionAndGenerateRequest() succeeds or generates an error. - void CreateSessionAndExpect(EmeInitDataType data_type, - const std::vector<uint8>& key_id, - ExpectedResult expected_result) { - DCHECK(!key_id.empty()); - - if (expected_result == SUCCESS) { - EXPECT_CALL(*this, - OnSessionMessage(IsNotEmpty(), _, _, GURL::EmptyGURL())); - } - - adapter_->CreateSessionAndGenerateRequest( - MediaKeys::TEMPORARY_SESSION, data_type, key_id, - CreateSessionPromise(expected_result)); - RunUntilIdle(); - } - - // Loads the session specified by |session_id|. |expected_result| tests - // that LoadSession() succeeds or generates an error. - void LoadSessionAndExpect(const std::string& session_id, - ExpectedResult expected_result) { - DCHECK(!session_id.empty()); - ASSERT_EQ(expected_result, FAILURE) << "LoadSession not supported."; - - adapter_->LoadSession(MediaKeys::TEMPORARY_SESSION, session_id, - CreateSessionPromise(expected_result)); - RunUntilIdle(); - } - - // Updates the session specified by |session_id| with |key|. |expected_result| - // tests that the update succeeds or generates an error. |new_key_expected| - // is the expected parameter when the SessionKeysChange event happens. - void UpdateSessionAndExpect(std::string session_id, - const std::string& key, - ExpectedResult expected_result, - bool new_key_expected) { - DCHECK(!key.empty()); - - if (expected_result == SUCCESS) { - EXPECT_CALL(*this, - OnSessionKeysChangeCalled(session_id, new_key_expected)); - } else { - EXPECT_CALL(*this, OnSessionKeysChangeCalled(_, _)).Times(0); - } - - adapter_->UpdateSession(session_id, - std::vector<uint8>(key.begin(), key.end()), - CreatePromise(expected_result)); - RunUntilIdle(); - } - - base::FilePath ExternalClearKeyLibrary() { return library_path_; } - - std::string SessionId() { return session_id_; } - - private: - void SetUp() override { - // Determine the location of the CDM. It is expected to be in the same - // directory as the current module. - base::FilePath current_module_dir; - ASSERT_TRUE(PathService::Get(base::DIR_MODULE, ¤t_module_dir)); - library_path_ = - current_module_dir.Append(base::FilePath(kExternalClearKeyCdmFileName)); - ASSERT_TRUE(base::PathExists(library_path_)) << library_path_.value(); - - // Now load the CDM library. - base::NativeLibraryLoadError error; - library_.Reset(base::LoadNativeLibrary(library_path_, &error)); - ASSERT_TRUE(library_.is_valid()) << error.ToString(); - - // Call INITIALIZE_CDM_MODULE() - typedef void (*InitializeCdmFunc)(); - InitializeCdmFunc initialize_cdm_func = reinterpret_cast<InitializeCdmFunc>( - library_.GetFunctionPointer(MAKE_STRING(INITIALIZE_CDM_MODULE))); - ASSERT_TRUE(initialize_cdm_func) << "No INITIALIZE_CDM_MODULE in library"; - initialize_cdm_func(); - } - - void TearDown() override { - // Call DeinitializeCdmModule() - typedef void (*DeinitializeCdmFunc)(); - DeinitializeCdmFunc deinitialize_cdm_func = - reinterpret_cast<DeinitializeCdmFunc>( - library_.GetFunctionPointer("DeinitializeCdmModule")); - ASSERT_TRUE(deinitialize_cdm_func) - << "No DeinitializeCdmModule() in library"; - deinitialize_cdm_func(); - } - - void OnCdmCreated(ExpectedResult expected_result, - const scoped_refptr<MediaKeys>& cdm, - const std::string& error_message) { - if (cdm) { - EXPECT_EQ(expected_result, SUCCESS) << "CDM should not have loaded."; - adapter_ = cdm; - } else { - EXPECT_EQ(expected_result, FAILURE) << error_message; - } - } - - // Create a promise. |expected_result| is used to indicate how the promise - // should be fulfilled. - scoped_ptr<SimpleCdmPromise> CreatePromise(ExpectedResult expected_result) { - if (expected_result == SUCCESS) { - EXPECT_CALL(*this, OnResolve()); - } else { - EXPECT_CALL(*this, OnReject(_, _, IsNotEmpty())); - } - - scoped_ptr<SimpleCdmPromise> promise(new CdmCallbackPromise<>( - base::Bind(&CdmAdapterTest::OnResolve, base::Unretained(this)), - base::Bind(&CdmAdapterTest::OnReject, base::Unretained(this)))); - return promise.Pass(); - } - - // Create a promise to be used when a new session is created. - // |expected_result| is used to indicate how the promise should be fulfilled. - scoped_ptr<NewSessionCdmPromise> CreateSessionPromise( - ExpectedResult expected_result) { - if (expected_result == SUCCESS) { - EXPECT_CALL(*this, OnResolveWithSession(_)) - .WillOnce(SaveArg<0>(&session_id_)); - } else { - EXPECT_CALL(*this, OnReject(_, _, IsNotEmpty())); - } - - scoped_ptr<NewSessionCdmPromise> promise( - new CdmCallbackPromise<std::string>( - base::Bind(&CdmAdapterTest::OnResolveWithSession, - base::Unretained(this)), - base::Bind(&CdmAdapterTest::OnReject, base::Unretained(this)))); - return promise.Pass(); - } - - void RunUntilIdle() { message_loop_.RunUntilIdle(); } - - // Methods used for promise resolved/rejected. - MOCK_METHOD0(OnResolve, void()); - MOCK_METHOD1(OnResolveWithSession, void(const std::string& session_id)); - MOCK_METHOD3(OnReject, - void(MediaKeys::Exception exception_code, - uint32 system_code, - const std::string& error_message)); - - // Methods used for the events possibly generated by CdmAdapater. - MOCK_METHOD4(OnSessionMessage, - void(const std::string& session_id, - MediaKeys::MessageType message_type, - const std::vector<uint8_t>& message, - const GURL& legacy_destination_url)); - MOCK_METHOD1(OnSessionClosed, void(const std::string& session_id)); - MOCK_METHOD4(OnLegacySessionError, - void(const std::string& session_id, - MediaKeys::Exception exception, - uint32_t system_code, - const std::string& error_message)); - MOCK_METHOD2(OnSessionKeysChangeCalled, - void(const std::string& session_id, - bool has_additional_usable_key)); - void OnSessionKeysChange(const std::string& session_id, - bool has_additional_usable_key, - CdmKeysInfo keys_info) { - // MOCK methods don't like CdmKeysInfo. - OnSessionKeysChangeCalled(session_id, has_additional_usable_key); - } - MOCK_METHOD2(OnSessionExpirationUpdate, - void(const std::string& session_id, - const base::Time& new_expiry_time)); - - // Keep a reference to the CDM. - base::FilePath library_path_; - base::ScopedNativeLibrary library_; - - scoped_refptr<MediaKeys> adapter_; - - // |session_id_| is the latest result of calling CreateSession(). - std::string session_id_; - - base::MessageLoop message_loop_; - - DISALLOW_COPY_AND_ASSIGN(CdmAdapterTest); -}; - -TEST_F(CdmAdapterTest, Initialize) { - InitializeAndExpect(ExternalClearKeyLibrary(), SUCCESS); -} - -TEST_F(CdmAdapterTest, BadLibraryPath) { - InitializeAndExpect(base::FilePath(FILE_PATH_LITERAL("no_library_here")), - FAILURE); -} - -TEST_F(CdmAdapterTest, CreateWebmSession) { - InitializeAndExpect(ExternalClearKeyLibrary(), SUCCESS); - - std::vector<uint8> key_id(kKeyId, kKeyId + arraysize(kKeyId)); - CreateSessionAndExpect(EmeInitDataType::WEBM, key_id, SUCCESS); -} - -TEST_F(CdmAdapterTest, CreateKeyIdsSession) { - InitializeAndExpect(ExternalClearKeyLibrary(), SUCCESS); - - // Don't include the trailing /0 from the string in the data passed in. - std::vector<uint8> key_id(kKeyIdAsJWK, - kKeyIdAsJWK + arraysize(kKeyIdAsJWK) - 1); - CreateSessionAndExpect(EmeInitDataType::KEYIDS, key_id, SUCCESS); -} - -TEST_F(CdmAdapterTest, CreateCencSession) { - InitializeAndExpect(ExternalClearKeyLibrary(), SUCCESS); - - std::vector<uint8> key_id(kKeyIdAsPssh, - kKeyIdAsPssh + arraysize(kKeyIdAsPssh)); -#if defined(USE_PROPRIETARY_CODECS) - CreateSessionAndExpect(EmeInitDataType::CENC, key_id, SUCCESS); -#else - CreateSessionAndExpect(EmeInitDataType::CENC, key_id, FAILURE); -#endif -} - -TEST_F(CdmAdapterTest, CreateSessionWithBadData) { - InitializeAndExpect(ExternalClearKeyLibrary(), SUCCESS); - - // Use |kKeyId| but specify KEYIDS format. - std::vector<uint8> key_id(kKeyId, kKeyId + arraysize(kKeyId)); - CreateSessionAndExpect(EmeInitDataType::KEYIDS, key_id, FAILURE); -} - -TEST_F(CdmAdapterTest, LoadSession) { - InitializeAndExpect(ExternalClearKeyLibrary(), SUCCESS); - - // LoadSession() is not supported by AesDecryptor. - std::vector<uint8> key_id(kKeyId, kKeyId + arraysize(kKeyId)); - CreateSessionAndExpect(EmeInitDataType::KEYIDS, key_id, FAILURE); -} - -TEST_F(CdmAdapterTest, UpdateSession) { - InitializeAndExpect(ExternalClearKeyLibrary(), SUCCESS); - - std::vector<uint8> key_id(kKeyId, kKeyId + arraysize(kKeyId)); - CreateSessionAndExpect(EmeInitDataType::WEBM, key_id, SUCCESS); - - UpdateSessionAndExpect(SessionId(), kKeyAsJWK, SUCCESS, true); -} - -TEST_F(CdmAdapterTest, UpdateSessionWithBadData) { - InitializeAndExpect(ExternalClearKeyLibrary(), SUCCESS); - - std::vector<uint8> key_id(kKeyId, kKeyId + arraysize(kKeyId)); - CreateSessionAndExpect(EmeInitDataType::WEBM, key_id, SUCCESS); - - UpdateSessionAndExpect(SessionId(), "random data", FAILURE, true); -} - -} // namespace media
diff --git a/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc b/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc index 61f0820..f6c7781 100644 --- a/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc +++ b/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc
@@ -212,15 +212,23 @@ } } +template<typename Type> +class ScopedResetter { + public: + explicit ScopedResetter(Type* object) : object_(object) {} + ~ScopedResetter() { object_->Reset(); } + + private: + Type* const object_; +}; + void INITIALIZE_CDM_MODULE() { - DVLOG(1) << __FUNCTION__; #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER) av_register_all(); #endif // CLEAR_KEY_CDM_USE_FFMPEG_DECODER } void DeinitializeCdmModule() { - DVLOG(1) << __FUNCTION__; } void* CreateCdmInstance(int cdm_interface_version, @@ -247,8 +255,7 @@ return NULL; // TODO(jrummell): Obtain the proper origin for this instance. - GURL empty_gurl; - return new media::ClearKeyCdm(host, key_system_string, empty_gurl); + return new media::ClearKeyCdm(host, key_system_string, GURL::EmptyGURL()); } const char* GetCdmVersion() {
diff --git a/media/media.gyp b/media/media.gyp index b56a23b..26760c5d 100644 --- a/media/media.gyp +++ b/media/media.gyp
@@ -1389,15 +1389,6 @@ 'filters/decrypting_video_decoder_unittest.cc', ], }], - # If ExternalClearKey is built, we can test CdmAdapter. - ['enable_pepper_cdms == 1', { - 'dependencies': [ - 'clearkeycdm', - ], - 'sources': [ - 'cdm/cdm_adapter_unittest.cc', - ], - }], ['target_arch != "arm" and chromeos == 1 and use_x11 == 1', { 'sources': [ 'filters/h264_bitstream_buffer_unittest.cc',
diff --git a/net/dns/dns_session.cc b/net/dns/dns_session.cc index 4d8f61e..9ea2db9 100644 --- a/net/dns/dns_session.cc +++ b/net/dns/dns_session.cc
@@ -93,8 +93,8 @@ UMA_HISTOGRAM_CUSTOM_COUNTS( "AsyncDNS.ServerCount", config_.nameservers.size(), 0, 10, 11); for (size_t i = 0; i < config_.nameservers.size(); ++i) { - server_stats_.push_back(new ServerStats(config_.timeout, - rtt_buckets_.Pointer())); + server_stats_.push_back(make_scoped_ptr( + new ServerStats(config_.timeout, rtt_buckets_.Pointer()))); } }
diff --git a/net/dns/dns_session.h b/net/dns/dns_session.h index e878a57..48af67fb 100644 --- a/net/dns/dns_session.h +++ b/net/dns/dns_session.h
@@ -10,7 +10,6 @@ #include "base/lazy_instance.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" -#include "base/memory/scoped_vector.h" #include "base/metrics/bucket_ranges.h" #include "base/time/time.h" #include "net/base/net_export.h" @@ -131,7 +130,7 @@ struct ServerStats; // Track runtime statistics of each DNS server. - ScopedVector<ServerStats> server_stats_; + std::vector<scoped_ptr<ServerStats>> server_stats_; // Buckets shared for all |ServerStats::rtt_histogram|. struct RttBuckets : public base::BucketRanges {
diff --git a/third_party/WebKit/Source/bindings/core/v8/BindingSecurity.cpp b/third_party/WebKit/Source/bindings/core/v8/BindingSecurity.cpp index 72fe57dc..9654ddf 100644 --- a/third_party/WebKit/Source/bindings/core/v8/BindingSecurity.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/BindingSecurity.cpp
@@ -80,9 +80,14 @@ return canAccessFrame(isolate, accessingWindow, target->securityContext()->securityOrigin(), target->domWindow(), exceptionState); } +bool BindingSecurity::shouldAllowAccessToNode(v8::Isolate* isolate, LocalDOMWindow* accessingWindow, Node* target, SecurityReportingOption reportingOption) +{ + return target && canAccessFrame(isolate, accessingWindow, target->document().securityOrigin(), target->document().domWindow(), reportingOption); +} + bool BindingSecurity::shouldAllowAccessToNode(v8::Isolate* isolate, LocalDOMWindow* accessingWindow, Node* target, ExceptionState& exceptionState) { return target && canAccessFrame(isolate, accessingWindow, target->document().securityOrigin(), target->document().domWindow(), exceptionState); } -} +} // namespace blink
diff --git a/third_party/WebKit/Source/bindings/core/v8/BindingSecurity.h b/third_party/WebKit/Source/bindings/core/v8/BindingSecurity.h index 9fed5178..f8fbe35 100644 --- a/third_party/WebKit/Source/bindings/core/v8/BindingSecurity.h +++ b/third_party/WebKit/Source/bindings/core/v8/BindingSecurity.h
@@ -51,7 +51,11 @@ class BindingSecurity { STATIC_ONLY(BindingSecurity); public: + // Check the access to the return value. + static bool shouldAllowAccessToNode(v8::Isolate*, LocalDOMWindow* accessingWindow, Node*, SecurityReportingOption); static bool shouldAllowAccessToNode(v8::Isolate*, LocalDOMWindow* accessingWindow, Node*, ExceptionState&); + + // Check the access to the receiver. CORE_EXPORT static bool shouldAllowAccessToFrame(v8::Isolate*, LocalDOMWindow* accessingWindow, Frame*, SecurityReportingOption = ReportSecurityError); CORE_EXPORT static bool shouldAllowAccessToFrame(v8::Isolate*, LocalDOMWindow* accessingWindow, Frame*, ExceptionState&); };
diff --git a/third_party/WebKit/Source/bindings/core/v8/custom/V8WindowCustom.cpp b/third_party/WebKit/Source/bindings/core/v8/custom/V8WindowCustom.cpp index d5a3f9a..b53b987 100644 --- a/third_party/WebKit/Source/bindings/core/v8/custom/V8WindowCustom.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/custom/V8WindowCustom.cpp
@@ -108,12 +108,7 @@ { LocalDOMWindow* impl = toLocalDOMWindow(V8Window::toImpl(info.Holder())); - // Do the security check against the parent frame rather than - // frameElement() itself, so that a remote parent frame can be handled - // properly. In that case, there's no frameElement(), yet we should still - // return null and deny access. - Frame* target = impl->frame() ? impl->frame()->tree().parent() : nullptr; - if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), target, DoNotReportSecurityError)) { + if (!BindingSecurity::shouldAllowAccessToNode(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl->frameElement(), DoNotReportSecurityError)) { v8SetReturnValueNull(info); return; }
diff --git a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp index 65b8ef84..f5b3344 100644 --- a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp +++ b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
@@ -724,10 +724,9 @@ Element* LocalDOMWindow::frameElement() const { - if (!frame()) + if (!(frame() && frame()->owner() && frame()->owner()->isLocal())) return nullptr; - // The bindings security check should ensure we're same origin... return toHTMLFrameOwnerElement(frame()->owner()); }
diff --git a/third_party/WebKit/Source/core/html/HTMLElement.cpp b/third_party/WebKit/Source/core/html/HTMLElement.cpp index c85256a..f0f31f0 100644 --- a/third_party/WebKit/Source/core/html/HTMLElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLElement.cpp
@@ -85,7 +85,7 @@ String HTMLElement::nodeName() const { // localNameUpper may intern and cache an AtomicString. - RELEASE_ASSERT(isMainThread()); + ASSERT(isMainThread()); // FIXME: Would be nice to have an atomicstring lookup based off uppercase // chars that does not have to copy the string on a hit in the hash.
diff --git a/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp b/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp index 817c18f..845e3ed 100644 --- a/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp
@@ -782,7 +782,6 @@ // Manual selection anchor is reset when manipulating the select programmatically. m_activeSelectionAnchorIndex = -1; setOptionsChangedOnLayoutObject(); - setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::ControlValue)); if (!inDocument()) { if (HTMLOptionsCollection* collection = cachedCollection<HTMLOptionsCollection>(SelectOptions)) collection->invalidateCache();
diff --git a/third_party/WebKit/Source/core/inspector/InspectedFrames.h b/third_party/WebKit/Source/core/inspector/InspectedFrames.h index 00aa5b00..b7682404 100644 --- a/third_party/WebKit/Source/core/inspector/InspectedFrames.h +++ b/third_party/WebKit/Source/core/inspector/InspectedFrames.h
@@ -6,6 +6,7 @@ #define InspectedFrames_h #include "core/CoreExport.h" +#include "platform/heap/Handle.h" #include "wtf/Forward.h" #include "wtf/Noncopyable.h" @@ -13,10 +14,12 @@ class LocalFrame; -class CORE_EXPORT InspectedFrames { +class CORE_EXPORT InspectedFrames final : public NoBaseWillBeGarbageCollectedFinalized<InspectedFrames> { WTF_MAKE_NONCOPYABLE(InspectedFrames); + USING_FAST_MALLOC_WILL_BE_REMOVED(InspectedFrames); public: class CORE_EXPORT Iterator { + STACK_ALLOCATED(); public: Iterator operator++(int); Iterator& operator++(); @@ -27,19 +30,30 @@ private: friend class InspectedFrames; Iterator(LocalFrame* root, LocalFrame* current); - LocalFrame* m_root; - LocalFrame* m_current; + RawPtrWillBeMember<LocalFrame> m_root; + RawPtrWillBeMember<LocalFrame> m_current; }; - explicit InspectedFrames(LocalFrame* root); + static PassOwnPtrWillBeRawPtr<InspectedFrames> create(LocalFrame* root) + { + return adoptPtrWillBeNoop(new InspectedFrames(root)); + } + LocalFrame* root() { return m_root; } bool contains(LocalFrame*) const; LocalFrame* frameWithSecurityOrigin(const String& originRawString); Iterator begin(); Iterator end(); + DEFINE_INLINE_TRACE() + { + visitor->trace(m_root); + } + private: - LocalFrame* m_root; + explicit InspectedFrames(LocalFrame*); + + RawPtrWillBeMember<LocalFrame> m_root; }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.cpp index 62ff7b5..4df7ecd 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.cpp
@@ -469,6 +469,7 @@ DEFINE_TRACE(InspectorAnimationAgent) { #if ENABLE(OILPAN) + visitor->trace(m_inspectedFrames); visitor->trace(m_domAgent); visitor->trace(m_cssAgent); visitor->trace(m_injectedScriptManager);
diff --git a/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.h b/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.h index 225b326..ace5214 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.h +++ b/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.h
@@ -71,7 +71,7 @@ Animation* animationClone(Animation*); String createCSSId(Animation&); - InspectedFrames* m_inspectedFrames; + RawPtrWillBeMember<InspectedFrames> m_inspectedFrames; RawPtrWillBeMember<InspectorDOMAgent> m_domAgent; RawPtrWillBeMember<InspectorCSSAgent> m_cssAgent; RawPtrWillBeMember<InjectedScriptManager> m_injectedScriptManager;
diff --git a/third_party/WebKit/Source/core/inspector/InspectorApplicationCacheAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorApplicationCacheAgent.cpp index 8e336691..2278185c 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorApplicationCacheAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorApplicationCacheAgent.cpp
@@ -201,8 +201,8 @@ DEFINE_TRACE(InspectorApplicationCacheAgent) { + visitor->trace(m_inspectedFrames); InspectorBaseAgent::trace(visitor); } } // namespace blink -
diff --git a/third_party/WebKit/Source/core/inspector/InspectorApplicationCacheAgent.h b/third_party/WebKit/Source/core/inspector/InspectorApplicationCacheAgent.h index 2d47b59..edc1fdb 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorApplicationCacheAgent.h +++ b/third_party/WebKit/Source/core/inspector/InspectorApplicationCacheAgent.h
@@ -66,14 +66,15 @@ void getApplicationCacheForFrame(ErrorString*, const String& frameId, RefPtr<TypeBuilder::ApplicationCache::ApplicationCache>&) override; private: - InspectorApplicationCacheAgent(InspectedFrames*); + explicit InspectorApplicationCacheAgent(InspectedFrames*); + PassRefPtr<TypeBuilder::ApplicationCache::ApplicationCache> buildObjectForApplicationCache(const ApplicationCacheHost::ResourceInfoList&, const ApplicationCacheHost::CacheInfo&); PassRefPtr<TypeBuilder::Array<TypeBuilder::ApplicationCache::ApplicationCacheResource> > buildArrayForApplicationCacheResources(const ApplicationCacheHost::ResourceInfoList&); PassRefPtr<TypeBuilder::ApplicationCache::ApplicationCacheResource> buildObjectForApplicationCacheResource(const ApplicationCacheHost::ResourceInfo&); DocumentLoader* assertFrameWithDocumentLoader(ErrorString*, String frameId); - InspectedFrames* m_inspectedFrames; + RawPtrWillBeMember<InspectedFrames> m_inspectedFrames; }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp index 22564014..438214f 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp
@@ -1959,6 +1959,7 @@ DEFINE_TRACE(InspectorCSSAgent) { visitor->trace(m_domAgent); + visitor->trace(m_inspectedFrames); visitor->trace(m_resourceAgent); visitor->trace(m_resourceContentLoader); #if ENABLE(OILPAN)
diff --git a/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.h b/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.h index 0d9b5de..b509f91 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.h +++ b/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.h
@@ -210,7 +210,7 @@ void resetPseudoStates(); RawPtrWillBeMember<InspectorDOMAgent> m_domAgent; - InspectedFrames* m_inspectedFrames; + RawPtrWillBeMember<InspectedFrames> m_inspectedFrames; RawPtrWillBeMember<InspectorResourceAgent> m_resourceAgent; RawPtrWillBeMember<InspectorResourceContentLoader> m_resourceContentLoader;
diff --git a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp index 999d5671..9309d9f 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
@@ -2144,6 +2144,7 @@ DEFINE_TRACE(InspectorDOMAgent) { visitor->trace(m_domListener); + visitor->trace(m_inspectedFrames); visitor->trace(m_injectedScriptManager); #if ENABLE(OILPAN) visitor->trace(m_documentNodeToIdMap);
diff --git a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.h b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.h index f8ff183..6dbeb79 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.h +++ b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.h
@@ -245,7 +245,7 @@ RawPtrWillBeMember<InspectorRevalidateDOMTask> revalidateTask(); - InspectedFrames* m_inspectedFrames; + RawPtrWillBeMember<InspectedFrames> m_inspectedFrames; RawPtrWillBeMember<InjectedScriptManager> m_injectedScriptManager; Client* m_client; RawPtrWillBeMember<DOMListener> m_domListener;
diff --git a/third_party/WebKit/Source/core/inspector/InspectorInputAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorInputAgent.cpp index 57cbb06e..38e7a6d 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorInputAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorInputAgent.cpp
@@ -208,8 +208,8 @@ DEFINE_TRACE(InspectorInputAgent) { + visitor->trace(m_inspectedFrames); InspectorBaseAgent::trace(visitor); } } // namespace blink -
diff --git a/third_party/WebKit/Source/core/inspector/InspectorInputAgent.h b/third_party/WebKit/Source/core/inspector/InspectorInputAgent.h index 12bb726..6422132 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorInputAgent.h +++ b/third_party/WebKit/Source/core/inspector/InspectorInputAgent.h
@@ -61,7 +61,7 @@ private: explicit InspectorInputAgent(InspectedFrames*); - InspectedFrames* m_inspectedFrames; + RawPtrWillBeMember<InspectedFrames> m_inspectedFrames; };
diff --git a/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp index 8da31e8..9f9497d 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp
@@ -159,6 +159,7 @@ DEFINE_TRACE(InspectorLayerTreeAgent) { + visitor->trace(m_inspectedFrames); InspectorBaseAgent::trace(visitor); }
diff --git a/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.h b/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.h index 016fa3f7..c960f0e 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.h +++ b/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.h
@@ -103,7 +103,7 @@ void gatherGraphicsLayers(GraphicsLayer*, HashMap<int, int>& layerIdToNodeIdMap, RefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::Layer> >&); int idForNode(Node*); - InspectedFrames* m_inspectedFrames; + RawPtrWillBeMember<InspectedFrames> m_inspectedFrames; Vector<int, 2> m_pageOverlayLayerIds; typedef HashMap<String, RefPtr<PictureSnapshot> > SnapshotById;
diff --git a/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp index e53a831..61b9688 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp
@@ -789,6 +789,7 @@ DEFINE_TRACE(InspectorPageAgent) { + visitor->trace(m_inspectedFrames); visitor->trace(m_debuggerAgent); visitor->trace(m_inspectorResourceContentLoader); InspectorBaseAgent::trace(visitor);
diff --git a/third_party/WebKit/Source/core/inspector/InspectorPageAgent.h b/third_party/WebKit/Source/core/inspector/InspectorPageAgent.h index 63917a6..a34aaeb 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorPageAgent.h +++ b/third_party/WebKit/Source/core/inspector/InspectorPageAgent.h
@@ -143,7 +143,7 @@ PassRefPtr<TypeBuilder::Page::Frame> buildObjectForFrame(LocalFrame*); PassRefPtr<TypeBuilder::Page::FrameResourceTree> buildObjectForFrameTree(LocalFrame*); - InspectedFrames* m_inspectedFrames; + RawPtrWillBeMember<InspectedFrames> m_inspectedFrames; RawPtrWillBeMember<InspectorDebuggerAgent> m_debuggerAgent; Client* m_client; long m_lastScriptIdentifier;
diff --git a/third_party/WebKit/Source/core/inspector/InspectorResourceAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorResourceAgent.cpp index 8a4228a..3c89b41b 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorResourceAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorResourceAgent.cpp
@@ -411,6 +411,7 @@ DEFINE_TRACE(InspectorResourceAgent) { + visitor->trace(m_inspectedFrames); visitor->trace(m_resourcesData); visitor->trace(m_replayXHRs); visitor->trace(m_replayXHRsToBeDeleted);
diff --git a/third_party/WebKit/Source/core/inspector/InspectorResourceAgent.h b/third_party/WebKit/Source/core/inspector/InspectorResourceAgent.h index eebf270..d266102 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorResourceAgent.h +++ b/third_party/WebKit/Source/core/inspector/InspectorResourceAgent.h
@@ -165,7 +165,7 @@ bool getResponseBodyBlob(const String& requestId, PassRefPtrWillBeRawPtr<GetResponseBodyCallback>); - InspectedFrames* m_inspectedFrames; + RawPtrWillBeMember<InspectedFrames> m_inspectedFrames; String m_userAgentOverride; String m_hostId; OwnPtrWillBeMember<NetworkResourcesData> m_resourcesData;
diff --git a/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.cpp b/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.cpp index 5ce3fd9a..0a30818 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.cpp
@@ -93,7 +93,8 @@ { m_started = true; WillBeHeapVector<RawPtrWillBeMember<Document>> documents; - for (LocalFrame* frame : InspectedFrames(m_inspectedFrame)) { + OwnPtrWillBeRawPtr<InspectedFrames> inspectedFrames = InspectedFrames::create(m_inspectedFrame); + for (LocalFrame* frame : *inspectedFrames) { documents.append(frame->document()); documents.appendVector(InspectorPageAgent::importsForFrame(frame)); }
diff --git a/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.cpp index 219b5d0..cab7508 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.cpp
@@ -38,6 +38,7 @@ DEFINE_TRACE(InspectorTracingAgent) { visitor->trace(m_workerAgent); + visitor->trace(m_inspectedFrames); InspectorBaseAgent::trace(visitor); }
diff --git a/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.h b/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.h index ad6cf17..522f039 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.h +++ b/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.h
@@ -59,7 +59,7 @@ int m_layerTreeId; Client* m_client; RawPtrWillBeMember<InspectorWorkerAgent> m_workerAgent; - InspectedFrames* m_inspectedFrames; + RawPtrWillBeMember<InspectedFrames> m_inspectedFrames; }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/inspector/PageConsoleAgent.cpp b/third_party/WebKit/Source/core/inspector/PageConsoleAgent.cpp index 63e8a43..227b3e2 100644 --- a/third_party/WebKit/Source/core/inspector/PageConsoleAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/PageConsoleAgent.cpp
@@ -63,6 +63,7 @@ DEFINE_TRACE(PageConsoleAgent) { visitor->trace(m_inspectorDOMAgent); + visitor->trace(m_inspectedFrames); InspectorConsoleAgent::trace(visitor); }
diff --git a/third_party/WebKit/Source/core/inspector/PageConsoleAgent.h b/third_party/WebKit/Source/core/inspector/PageConsoleAgent.h index 8a689e5d..279c35c 100644 --- a/third_party/WebKit/Source/core/inspector/PageConsoleAgent.h +++ b/third_party/WebKit/Source/core/inspector/PageConsoleAgent.h
@@ -72,7 +72,7 @@ void clearMessages(ErrorString*) override; RawPtrWillBeMember<InspectorDOMAgent> m_inspectorDOMAgent; - InspectedFrames* m_inspectedFrames; + RawPtrWillBeMember<InspectedFrames> m_inspectedFrames; HashSet<WorkerGlobalScopeProxy*> m_workersWithEnabledConsole; static int s_enabledAgentCount;
diff --git a/third_party/WebKit/Source/core/inspector/PageDebuggerAgent.cpp b/third_party/WebKit/Source/core/inspector/PageDebuggerAgent.cpp index 0480a3a..6cb0c23 100644 --- a/third_party/WebKit/Source/core/inspector/PageDebuggerAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/PageDebuggerAgent.cpp
@@ -70,6 +70,7 @@ DEFINE_TRACE(PageDebuggerAgent) { + visitor->trace(m_inspectedFrames); visitor->trace(m_injectedScriptManager); InspectorDebuggerAgent::trace(visitor); }
diff --git a/third_party/WebKit/Source/core/inspector/PageDebuggerAgent.h b/third_party/WebKit/Source/core/inspector/PageDebuggerAgent.h index bf798d59..f0bbd41 100644 --- a/third_party/WebKit/Source/core/inspector/PageDebuggerAgent.h +++ b/third_party/WebKit/Source/core/inspector/PageDebuggerAgent.h
@@ -70,7 +70,7 @@ // V8DebuggerAgent::Client implemntation. bool canExecuteScripts() const; - InspectedFrames* m_inspectedFrames; + RawPtrWillBeMember<InspectedFrames> m_inspectedFrames; RawPtrWillBeMember<InjectedScriptManager> m_injectedScriptManager; HashMap<String, String> m_compiledScriptURLs; };
diff --git a/third_party/WebKit/Source/core/inspector/PageRuntimeAgent.cpp b/third_party/WebKit/Source/core/inspector/PageRuntimeAgent.cpp index d456478..4e8e789 100644 --- a/third_party/WebKit/Source/core/inspector/PageRuntimeAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/PageRuntimeAgent.cpp
@@ -62,6 +62,7 @@ DEFINE_TRACE(PageRuntimeAgent) { + visitor->trace(m_inspectedFrames); InspectorRuntimeAgent::trace(visitor); } @@ -175,4 +176,3 @@ } } // namespace blink -
diff --git a/third_party/WebKit/Source/core/inspector/PageRuntimeAgent.h b/third_party/WebKit/Source/core/inspector/PageRuntimeAgent.h index e6815d2..4584ef0 100644 --- a/third_party/WebKit/Source/core/inspector/PageRuntimeAgent.h +++ b/third_party/WebKit/Source/core/inspector/PageRuntimeAgent.h
@@ -66,7 +66,7 @@ void reportExecutionContextCreation(); void reportExecutionContext(ScriptState*, bool isPageContext, const String& origin, const String& frameId); - InspectedFrames* m_inspectedFrames; + RawPtrWillBeMember<InspectedFrames> m_inspectedFrames; bool m_mainWorldContextCreated; typedef HashMap<RefPtr<ScriptState>, int> ScriptStateToId; ScriptStateToId m_scriptStateToId;
diff --git a/third_party/WebKit/Source/modules/filesystem/InspectorFileSystemAgent.cpp b/third_party/WebKit/Source/modules/filesystem/InspectorFileSystemAgent.cpp index 63c79d4..9db56ac 100644 --- a/third_party/WebKit/Source/modules/filesystem/InspectorFileSystemAgent.cpp +++ b/third_party/WebKit/Source/modules/filesystem/InspectorFileSystemAgent.cpp
@@ -765,6 +765,7 @@ DEFINE_TRACE(InspectorFileSystemAgent) { + visitor->trace(m_inspectedFrames); InspectorBaseAgent::trace(visitor); }
diff --git a/third_party/WebKit/Source/modules/filesystem/InspectorFileSystemAgent.h b/third_party/WebKit/Source/modules/filesystem/InspectorFileSystemAgent.h index 3a2ee25..fab4370 100644 --- a/third_party/WebKit/Source/modules/filesystem/InspectorFileSystemAgent.h +++ b/third_party/WebKit/Source/modules/filesystem/InspectorFileSystemAgent.h
@@ -65,7 +65,7 @@ bool assertEnabled(ErrorString*); ExecutionContext* assertExecutionContextForOrigin(ErrorString*, SecurityOrigin*); - InspectedFrames* m_inspectedFrames; + RawPtrWillBeMember<InspectedFrames> m_inspectedFrames; bool m_enabled; };
diff --git a/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.cpp b/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.cpp index 487d7d1e4..b827876 100644 --- a/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.cpp +++ b/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.cpp
@@ -831,6 +831,7 @@ DEFINE_TRACE(InspectorIndexedDBAgent) { + visitor->trace(m_inspectedFrames); InspectorBaseAgent::trace(visitor); }
diff --git a/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.h b/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.h index a86fc86..0cc331f 100644 --- a/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.h +++ b/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.h
@@ -63,7 +63,7 @@ private: explicit InspectorIndexedDBAgent(InspectedFrames*); - InspectedFrames* m_inspectedFrames; + RawPtrWillBeMember<InspectedFrames> m_inspectedFrames; }; } // namespace blink
diff --git a/third_party/WebKit/Source/modules/storage/InspectorDOMStorageAgent.cpp b/third_party/WebKit/Source/modules/storage/InspectorDOMStorageAgent.cpp index 4c0eb81..8da4193cb 100644 --- a/third_party/WebKit/Source/modules/storage/InspectorDOMStorageAgent.cpp +++ b/third_party/WebKit/Source/modules/storage/InspectorDOMStorageAgent.cpp
@@ -210,7 +210,8 @@ if (!m_page->mainFrame()->isLocalFrame()) return nullptr; - LocalFrame* frame = InspectedFrames(m_page->deprecatedLocalMainFrame()).frameWithSecurityOrigin(securityOrigin); + OwnPtrWillBeRawPtr<InspectedFrames> inspectedFrames = InspectedFrames::create(m_page->deprecatedLocalMainFrame()); + LocalFrame* frame = inspectedFrames->frameWithSecurityOrigin(securityOrigin); if (!frame) { if (errorString) *errorString = "LocalFrame not found for the given security origin";
diff --git a/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp b/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp index 62258a2b..e21c2677 100644 --- a/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp +++ b/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp
@@ -320,7 +320,7 @@ , m_resourceContentLoader(InspectorResourceContentLoader::create(m_webLocalFrameImpl->frame())) , m_state(adoptPtrWillBeNoop(new InspectorCompositeState(this))) , m_overlay(overlay) - , m_inspectedFrames(adoptPtr(new InspectedFrames(m_webLocalFrameImpl->frame()))) + , m_inspectedFrames(InspectedFrames::create(m_webLocalFrameImpl->frame())) , m_inspectorAgent(nullptr) , m_domAgent(nullptr) , m_pageAgent(nullptr) @@ -413,6 +413,7 @@ visitor->trace(m_resourceContentLoader); visitor->trace(m_state); visitor->trace(m_overlay); + visitor->trace(m_inspectedFrames); visitor->trace(m_inspectorAgent); visitor->trace(m_domAgent); visitor->trace(m_pageAgent);
diff --git a/third_party/WebKit/Source/web/WebDevToolsAgentImpl.h b/third_party/WebKit/Source/web/WebDevToolsAgentImpl.h index 9ce980bb..f377d56 100644 --- a/third_party/WebKit/Source/web/WebDevToolsAgentImpl.h +++ b/third_party/WebKit/Source/web/WebDevToolsAgentImpl.h
@@ -143,7 +143,7 @@ OwnPtrWillBeMember<InspectorResourceContentLoader> m_resourceContentLoader; OwnPtrWillBeMember<InspectorCompositeState> m_state; OwnPtrWillBeMember<InspectorOverlay> m_overlay; - OwnPtr<InspectedFrames> m_inspectedFrames; + OwnPtrWillBeMember<InspectedFrames> m_inspectedFrames; RawPtrWillBeMember<InspectorInspectorAgent> m_inspectorAgent; RawPtrWillBeMember<InspectorDOMAgent> m_domAgent;
diff --git a/ui/file_manager/file_manager/foreground/js/main_window_component.js b/ui/file_manager/file_manager/foreground/js/main_window_component.js index c861a10e..0a1419e 100644 --- a/ui/file_manager/file_manager/foreground/js/main_window_component.js +++ b/ui/file_manager/file_manager/foreground/js/main_window_component.js
@@ -108,6 +108,8 @@ // Register events. ui.listContainer.element.addEventListener( 'keydown', this.onListKeyDown_.bind(this)); + ui.directoryTree.addEventListener( + 'keydown', this.onDirectoryTreeKeyDown_.bind(this)); ui.listContainer.element.addEventListener( ListContainer.EventType.TEXT_SEARCH, this.onTextSearch_.bind(this)); ui.listContainer.table.list.addEventListener( @@ -270,6 +272,28 @@ }; /** + * KeyDown event handler for the directory tree element. + * @param {Event} event Key event. + * @private + */ +MainWindowComponent.prototype.onDirectoryTreeKeyDown_ = function(event) { + // Enter => Change directory or perform default action. + if (util.getKeyModifiers(event) + event.keyIdentifier === 'Enter') { + var selectedItem = this.ui_.directoryTree.selectedItem; + if (!selectedItem) + return; + selectedItem.activate(); + if (this.dialogType_ !== DialogType.FULL_PAGE && + !selectedItem.hasAttribute('renaming') && + util.isSameEntry( + this.directoryModel_.getCurrentDirEntry(), selectedItem.entry) && + !this.ui_.dialogFooter.okButton.disabled) { + this.ui_.dialogFooter.okButton.click(); + } + } +}; + +/** * KeyDown event handler for the div#list-container element. * @param {Event} event Key event. * @private
diff --git a/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js b/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js index e4d2778..9b974c2 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js +++ b/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js
@@ -1275,19 +1275,6 @@ }; /** - * Handles keydown events on the tree and activates the selected item on Enter. - * @param {Event} e The click event object. - * @override - */ -DirectoryTree.prototype.handleKeyDown = function(e) { - cr.ui.Tree.prototype.handleKeyDown.call(this, e); - if (util.getKeyModifiers(e) === '' && e.keyIdentifier === 'Enter') { - if (this.selectedItem) - this.selectedItem.activate(); - } -}; - -/** * Invoked when the filter is changed. * @private */