Update from https://crrev.com/304121
Includes DEPS updates and port of
https://codereview.chromium.org/665223004 to accomodate skia API change
on android.
Review URL: https://codereview.chromium.org/723343002
diff --git a/allocator/BUILD.gn b/allocator/BUILD.gn
index 510c3d3..d9ff4c5 100644
--- a/allocator/BUILD.gn
+++ b/allocator/BUILD.gn
@@ -37,7 +37,7 @@
}
}
-if (!is_android) {
+if (use_allocator == "tcmalloc") {
# tcmalloc currently won't compile on Android.
source_set("tcmalloc") {
tcmalloc_dir = "//third_party/tcmalloc/chromium"
diff --git a/android/java/src/org/chromium/base/SystemMessageHandler.java b/android/java/src/org/chromium/base/SystemMessageHandler.java
index 10f8d55..fd3dc5a 100644
--- a/android/java/src/org/chromium/base/SystemMessageHandler.java
+++ b/android/java/src/org/chromium/base/SystemMessageHandler.java
@@ -5,12 +5,9 @@
package org.chromium.base;
import android.os.Handler;
-import android.os.Looper;
import android.os.Message;
-import android.os.MessageQueue;
import android.util.Log;
-import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -25,23 +22,31 @@
private long mMessagePumpDelegateNative = 0;
private long mDelayedScheduledTimeTicks = 0;
- // The following members are used to detect and trace the presence of sync
- // barriers in Android's MessageQueue. Note that this detection is
- // experimental, temporary and intended only for diagnostic purposes.
- private MessageQueue mMessageQueue;
- private Field mMessageQueueMessageField;
- private Field mMessageTargetField;
- private boolean mQueueHasSyncBarrier;
- private long mSyncBarrierTraceId;
+ // Reflected API for marking a message as asynchronous. This is a workaround
+ // to provide fair Chromium task dispatch when served by the Android UI
+ // thread's Looper, avoiding stalls when the Looper has a sync barrier.
+ // Note: Use of this API is experimental and likely to evolve in the future.
+ private Method mMessageMethodSetAsynchronous;
private SystemMessageHandler(long messagePumpDelegateNative) {
mMessagePumpDelegateNative = messagePumpDelegateNative;
- tryEnableSyncBarrierDetection();
+
+ try {
+ Class<?> messageClass = Class.forName("android.os.Message");
+ mMessageMethodSetAsynchronous = messageClass.getMethod(
+ "setAsynchronous", new Class[]{boolean.class});
+ } catch (ClassNotFoundException e) {
+ Log.e(TAG, "Failed to find android.os.Message class:" + e);
+ } catch (NoSuchMethodException e) {
+ Log.e(TAG, "Failed to load Message.setAsynchronous method:" + e);
+ } catch (RuntimeException e) {
+ Log.e(TAG, "Exception while loading Message.setAsynchronous method: " + e);
+ }
+
}
@Override
public void handleMessage(Message msg) {
- updateWhetherQueueHasBlockingSyncBarrier();
if (msg.what == DELAYED_SCHEDULED_WORK) {
mDelayedScheduledTimeTicks = 0;
}
@@ -51,9 +56,7 @@
@SuppressWarnings("unused")
@CalledByNative
private void scheduleWork() {
- updateWhetherQueueHasBlockingSyncBarrier();
- if (mQueueHasSyncBarrier) TraceEvent.instant("SystemMessageHandler:immediateWorkBlocked");
- sendEmptyMessage(SCHEDULED_WORK);
+ sendMessage(obtainAsyncMessage(SCHEDULED_WORK));
}
@SuppressWarnings("unused")
@@ -63,97 +66,39 @@
removeMessages(DELAYED_SCHEDULED_WORK);
}
mDelayedScheduledTimeTicks = delayedTimeTicks;
- updateWhetherQueueHasBlockingSyncBarrier();
- if (mQueueHasSyncBarrier) TraceEvent.instant("SystemMessageHandler:delayedWorkBlocked");
- sendEmptyMessageDelayed(DELAYED_SCHEDULED_WORK, millis);
+ sendMessageDelayed(obtainAsyncMessage(DELAYED_SCHEDULED_WORK), millis);
}
@SuppressWarnings("unused")
@CalledByNative
private void removeAllPendingMessages() {
- updateWhetherQueueHasBlockingSyncBarrier();
removeMessages(SCHEDULED_WORK);
removeMessages(DELAYED_SCHEDULED_WORK);
}
- private void updateWhetherQueueHasBlockingSyncBarrier() {
- if (mMessageQueue == null) return;
- // As barrier detection is only used for tracing, early out when tracing
- // is disabled to avoid any potential performance penalties.
- if (!TraceEvent.enabled()) {
- mQueueHasSyncBarrier = false;
- return;
+ private Message obtainAsyncMessage(int what) {
+ Message msg = Message.obtain();
+ msg.what = what;
+ if (mMessageMethodSetAsynchronous != null) {
+ // If invocation fails, assume this is indicative of future
+ // failures, and avoid log spam by nulling the reflected method.
+ try {
+ mMessageMethodSetAsynchronous.invoke(msg, true);
+ } catch (IllegalAccessException e) {
+ Log.e(TAG, "Illegal access to asynchronous message creation, disabling.");
+ mMessageMethodSetAsynchronous = null;
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Illegal argument for asynchronous message creation, disabling.");
+ mMessageMethodSetAsynchronous = null;
+ } catch (InvocationTargetException e) {
+ Log.e(TAG, "Invocation exception during asynchronous message creation, disabling.");
+ mMessageMethodSetAsynchronous = null;
+ } catch (RuntimeException e) {
+ Log.e(TAG, "Runtime exception during asynchronous message creation, disabling.");
+ mMessageMethodSetAsynchronous = null;
+ }
}
- Message queueHead = (Message) getField(mMessageQueue, mMessageQueueMessageField);
- setqueueHasSyncBarrier(isSyncBarrierMessage(queueHead));
- }
-
- private boolean isSyncBarrierMessage(Message message) {
- if (message == null) return false;
- // Sync barrier messages have null targets.
- return getField(message, mMessageTargetField) == null;
- }
-
- private void tryEnableSyncBarrierDetection() {
- assert mMessageQueue == null;
-
- boolean success = false;
- try {
- Method getQueueMethod = Looper.class.getMethod("getQueue", new Class[]{});
- mMessageQueue = (MessageQueue) getQueueMethod.invoke(getLooper());
-
- mMessageQueueMessageField = mMessageQueue.getClass().getDeclaredField("mMessages");
- mMessageQueueMessageField.setAccessible(true);
-
- mMessageTargetField = Message.class.getDeclaredField("target");
- mMessageTargetField.setAccessible(true);
-
- mSyncBarrierTraceId = hashCode();
-
- success = true;
- } catch (NoSuchMethodException e) {
- Log.e(TAG, "Failed to load method: " + e);
- } catch (NoSuchFieldException e) {
- Log.e(TAG, "Failed to load field: " + e);
- } catch (InvocationTargetException e) {
- Log.e(TAG, "Failed invocation: " + e);
- } catch (IllegalAccessException e) {
- Log.e(TAG, "Illegal access to reflected invocation: " + e);
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Illegal argument to reflected invocation: " + e);
- } catch (RuntimeException e) {
- Log.e(TAG, e.toString());
- } finally {
- if (!success) disableSyncBarrierDetection();
- }
- }
-
- private void disableSyncBarrierDetection() {
- Log.e(TAG, "Unexpected error with sync barrier detection, disabling.");
- mMessageQueue = null;
- mMessageQueueMessageField = null;
- mMessageTargetField = null;
- setqueueHasSyncBarrier(false);
- }
-
- private void setqueueHasSyncBarrier(boolean queueHasSyncBarrier) {
- if (queueHasSyncBarrier == mQueueHasSyncBarrier) return;
- mQueueHasSyncBarrier = queueHasSyncBarrier;
- if (mQueueHasSyncBarrier) {
- TraceEvent.startAsync("SyncBarrier", mSyncBarrierTraceId);
- } else {
- TraceEvent.finishAsync("SyncBarrier", mSyncBarrierTraceId);
- }
- }
-
- private Object getField(Object object, Field field) {
- try {
- return field.get(object);
- } catch (IllegalAccessException e) {
- Log.e(TAG, "Failed field access: " + e);
- disableSyncBarrierDetection();
- }
- return null;
+ return msg;
}
@CalledByNative
diff --git a/android/linker/linker_jni.cc b/android/linker/linker_jni.cc
index b3ed651..1a11639 100644
--- a/android/linker/linker_jni.cc
+++ b/android/linker/linker_jni.cc
@@ -664,7 +664,7 @@
__FUNCTION__, library_name_c_str, apkfile_name_c_str);
jboolean mappable = crazy_linker_check_library_is_mappable_in_zip_file(
apkfile_name_c_str, library_name_c_str) == CRAZY_STATUS_SUCCESS;
- LOG_INFO("%s: %s\n", __FUNCTION__, aligned ? "Aligned" : "NOT aligned");
+ LOG_INFO("%s: %s\n", __FUNCTION__, mappable ? "Mappable" : "NOT mappable");
return mappable;
}
diff --git a/base64.h b/base64.h
index 43d8f76..def9b67 100644
--- a/base64.h
+++ b/base64.h
@@ -12,11 +12,12 @@
namespace base {
-// Encodes the input string in base64.
+// Encodes the input string in base64. The encoding can be done in-place.
BASE_EXPORT void Base64Encode(const StringPiece& input, std::string* output);
// Decodes the base64 input string. Returns true if successful and false
-// otherwise. The output string is only modified if successful.
+// otherwise. The output string is only modified if successful. The decoding can
+// be done in-place.
BASE_EXPORT bool Base64Decode(const StringPiece& input, std::string* output);
} // namespace base
diff --git a/base64_unittest.cc b/base64_unittest.cc
index 9b23194..91651f4 100644
--- a/base64_unittest.cc
+++ b/base64_unittest.cc
@@ -24,4 +24,17 @@
EXPECT_EQ(kText, decoded);
}
+TEST(Base64Test, InPlace) {
+ const std::string kText = "hello world";
+ const std::string kBase64Text = "aGVsbG8gd29ybGQ=";
+ std::string text(kText);
+
+ Base64Encode(text, &text);
+ EXPECT_EQ(kBase64Text, text);
+
+ bool ok = Base64Decode(text, &text);
+ EXPECT_TRUE(ok);
+ EXPECT_EQ(text, kText);
+}
+
} // namespace base
diff --git a/files/file.h b/files/file.h
index 4110d51..7b6366c 100644
--- a/files/file.h
+++ b/files/file.h
@@ -19,6 +19,7 @@
#include "base/base_export.h"
#include "base/basictypes.h"
#include "base/files/scoped_file.h"
+#include "base/gtest_prod_util.h"
#include "base/move.h"
#include "base/time/time.h"
@@ -26,6 +27,8 @@
#include "base/win/scoped_handle.h"
#endif
+FORWARD_DECLARE_TEST(FileTest, MemoryCorruption);
+
namespace base {
class FilePath;
@@ -296,12 +299,59 @@
static std::string ErrorToString(Error error);
private:
+ FRIEND_TEST_ALL_PREFIXES(::FileTest, MemoryCorruption);
+
+#if defined(OS_POSIX)
+ // Encloses a single ScopedFD, saving a cheap tamper resistent memory checksum
+ // alongside it. This checksum is validated at every access, allowing early
+ // detection of memory corruption.
+
+ // TODO(gavinp): This is in place temporarily to help us debug
+ // https://crbug.com/424562 , which can't be reproduced in valgrind. Remove
+ // this code after we have fixed this issue.
+ class MemoryCheckingScopedFD {
+ public:
+ MemoryCheckingScopedFD();
+ MemoryCheckingScopedFD(int fd);
+ ~MemoryCheckingScopedFD();
+
+ bool is_valid() const { Check(); return file_.is_valid(); }
+ int get() const { Check(); return file_.get(); }
+
+ void reset() { Check(); file_.reset(); UpdateChecksum(); }
+ void reset(int fd) { Check(); file_.reset(fd); UpdateChecksum(); }
+ int release() {
+ Check();
+ int fd = file_.release();
+ UpdateChecksum();
+ return fd;
+ }
+
+ private:
+ FRIEND_TEST_ALL_PREFIXES(::FileTest, MemoryCorruption);
+
+ // Computes the checksum for the current value of |file_|. Returns via an
+ // out parameter to guard against implicit conversions of unsigned integral
+ // types.
+ void ComputeMemoryChecksum(unsigned int* out_checksum) const;
+
+ // Confirms that the current |file_| and |file_memory_checksum_| agree,
+ // failing a CHECK if they do not.
+ void Check() const;
+
+ void UpdateChecksum();
+
+ ScopedFD file_;
+ unsigned int file_memory_checksum_;
+ };
+#endif
+
void SetPlatformFile(PlatformFile file);
#if defined(OS_WIN)
win::ScopedHandle file_;
#elif defined(OS_POSIX)
- ScopedFD file_;
+ MemoryCheckingScopedFD file_;
#endif
Error error_details_;
diff --git a/files/file_posix.cc b/files/file_posix.cc
index 43684b5..3d229e4 100644
--- a/files/file_posix.cc
+++ b/files/file_posix.cc
@@ -483,6 +483,49 @@
}
}
+File::MemoryCheckingScopedFD::MemoryCheckingScopedFD() {
+ UpdateChecksum();
+}
+
+File::MemoryCheckingScopedFD::MemoryCheckingScopedFD(int fd) : file_(fd) {
+ UpdateChecksum();
+}
+
+File::MemoryCheckingScopedFD::~MemoryCheckingScopedFD() {}
+
+// static
+void File::MemoryCheckingScopedFD::ComputeMemoryChecksum(
+ unsigned int* out_checksum) const {
+ // Use a single iteration of a linear congruentional generator (lcg) to
+ // provide a cheap checksum unlikely to be accidentally matched by a random
+ // memory corruption.
+
+ // By choosing constants that satisfy the Hull-Duebell Theorem on lcg cycle
+ // length, we insure that each distinct fd value maps to a distinct checksum,
+ // which maximises the utility of our checksum.
+
+ // This code uses "unsigned int" throughout for its defined modular semantics,
+ // which implicitly gives us a divisor that is a power of two.
+
+ const unsigned int kMultiplier = 13035 * 4 + 1;
+ COMPILE_ASSERT(((kMultiplier - 1) & 3) == 0, pred_must_be_multiple_of_four);
+ const unsigned int kIncrement = 1595649551;
+ COMPILE_ASSERT(kIncrement & 1, must_be_coprime_to_powers_of_two);
+
+ *out_checksum =
+ static_cast<unsigned int>(file_.get()) * kMultiplier + kIncrement;
+}
+
+void File::MemoryCheckingScopedFD::Check() const {
+ unsigned int computed_checksum;
+ ComputeMemoryChecksum(&computed_checksum);
+ CHECK_EQ(file_memory_checksum_, computed_checksum) << "corrupted fd memory";
+}
+
+void File::MemoryCheckingScopedFD::UpdateChecksum() {
+ ComputeMemoryChecksum(&file_memory_checksum_);
+}
+
void File::SetPlatformFile(PlatformFile file) {
DCHECK(!file_.is_valid());
file_.reset(file);
diff --git a/files/file_unittest.cc b/files/file_unittest.cc
index 6616f6a..3bc2db6 100644
--- a/files/file_unittest.cc
+++ b/files/file_unittest.cc
@@ -5,6 +5,7 @@
#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -466,3 +467,71 @@
EXPECT_EQ(0, info.size);
}
#endif // defined(OS_WIN)
+
+#if defined(OS_POSIX) && defined(GTEST_HAS_DEATH_TEST)
+TEST(FileTest, MemoryCorruption) {
+ {
+ // Test that changing the checksum value is detected.
+ base::File file;
+ EXPECT_NE(file.file_.file_memory_checksum_,
+ implicit_cast<unsigned int>(file.GetPlatformFile()));
+ file.file_.file_memory_checksum_ = file.GetPlatformFile();
+ EXPECT_DEATH(file.IsValid(), "");
+
+ file.file_.UpdateChecksum(); // Do not crash on File::~File().
+ }
+
+ {
+ // Test that changing the file descriptor value is detected.
+ base::File file;
+ file.file_.file_.reset(17);
+ EXPECT_DEATH(file.IsValid(), "");
+
+ // Do not crash on File::~File().
+ ignore_result(file.file_.file_.release());
+ file.file_.UpdateChecksum();
+ }
+
+ {
+ // Test that GetPlatformFile() checks for corruption.
+ base::File file;
+ file.file_.file_memory_checksum_ = file.GetPlatformFile();
+ EXPECT_DEATH(file.GetPlatformFile(), "");
+
+ file.file_.UpdateChecksum(); // Do not crash on File::~File().
+ }
+
+ {
+ // Test that the base::File destructor checks for corruption.
+ scoped_ptr<base::File> file(new File());
+ file->file_.file_memory_checksum_ = file->GetPlatformFile();
+ EXPECT_DEATH(file.reset(), "");
+
+ // Do not crash on this thread's destructor call.
+ file->file_.UpdateChecksum();
+ }
+
+ {
+ // Test that the base::File constructor checks for corruption.
+ base::File file;
+ file.file_.file_memory_checksum_ = file.GetPlatformFile();
+ EXPECT_DEATH(File f(file.Pass()), "");
+
+ file.file_.UpdateChecksum(); // Do not crash on File::~File().
+ }
+
+ {
+ // Test that doing IO checks for corruption.
+ base::File file;
+ file.file_.file_.reset(17); // A fake open FD value.
+
+ EXPECT_DEATH(file.Seek(File::FROM_BEGIN, 0), "");
+ EXPECT_DEATH(file.Read(0, NULL, 0), "");
+ EXPECT_DEATH(file.ReadAtCurrentPos(NULL, 0), "");
+ EXPECT_DEATH(file.Write(0, NULL, 0), "");
+
+ ignore_result(file.file_.file_.release());
+ file.file_.UpdateChecksum();
+ }
+}
+#endif // defined(OS_POSIX)
diff --git a/files/file_util_posix.cc b/files/file_util_posix.cc
index b8c0eeb..0bf41a5 100644
--- a/files/file_util_posix.cc
+++ b/files/file_util_posix.cc
@@ -28,8 +28,6 @@
#include <glib.h> // for g_get_home_dir()
#endif
-#include <fstream>
-
#include "base/basictypes.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
@@ -428,7 +426,7 @@
bool SetPosixFilePermissions(const FilePath& path,
int mode) {
ThreadRestrictions::AssertIOAllowed();
- DCHECK((mode & ~FILE_PERMISSION_MASK) == 0);
+ DCHECK_EQ(mode & ~FILE_PERMISSION_MASK, 0);
// Calls stat() so that we can preserve the higher bits like S_ISGID.
stat_wrapper_t stat_buf;
diff --git a/json/json_reader.cc b/json/json_reader.cc
index ad5a9d5..e17d450 100644
--- a/json/json_reader.cc
+++ b/json/json_reader.cc
@@ -31,7 +31,7 @@
"Dictionary keys must be quoted.";
JSONReader::JSONReader()
- : parser_(new internal::JSONParser(JSON_PARSE_RFC)) {
+ : JSONReader(JSON_PARSE_RFC) {
}
JSONReader::JSONReader(int options)
diff --git a/mac/bind_objc_block.h b/mac/bind_objc_block.h
index 9deb2d2..c31f26e 100644
--- a/mac/bind_objc_block.h
+++ b/mac/bind_objc_block.h
@@ -21,51 +21,32 @@
// BindBlock(^(const std::string& arg0, const std::string& arg1) {
// ...
// });
+//
+// These variadic templates will accommodate any number of arguments, however
+// the underlying templates in bind_internal.h and callback.h are limited to
+// seven total arguments, and the bound block itself is used as one of these
+// arguments, so functionally the templates are limited to binding blocks with
+// zero through six arguments.
namespace base {
namespace internal {
-// Helper functions to run the block contained in the parameter.
-template<typename R>
-R RunBlock(base::mac::ScopedBlock<R(^)()> block) {
- R(^extracted_block)() = block.get();
- return extracted_block();
-}
-
-template<typename R, typename A1>
-R RunBlock(base::mac::ScopedBlock<R(^)(A1)> block, A1 a) {
- R(^extracted_block)(A1) = block.get();
- return extracted_block(a);
-}
-
-template<typename R, typename A1, typename A2>
-R RunBlock(base::mac::ScopedBlock<R(^)(A1, A2)> block, A1 a, A2 b) {
- R(^extracted_block)(A1, A2) = block.get();
- return extracted_block(a, b);
+// Helper function to run the block contained in the parameter.
+template<typename R, typename... Args>
+R RunBlock(base::mac::ScopedBlock<R(^)(Args...)> block, Args... args) {
+ R(^extracted_block)(Args...) = block.get();
+ return extracted_block(args...);
}
} // namespace internal
-// Construct a callback with no argument from an objective-C block.
-template<typename R>
-base::Callback<R(void)> BindBlock(R(^block)()) {
- return base::Bind(&base::internal::RunBlock<R>,
- base::mac::ScopedBlock<R(^)()>(Block_copy(block)));
-}
-
-// Construct a callback with one argument from an objective-C block.
-template<typename R, typename A1>
-base::Callback<R(A1)> BindBlock(R(^block)(A1)) {
- return base::Bind(&base::internal::RunBlock<R, A1>,
- base::mac::ScopedBlock<R(^)(A1)>(Block_copy(block)));
-}
-
-// Construct a callback with two arguments from an objective-C block.
-template<typename R, typename A1, typename A2>
-base::Callback<R(A1, A2)> BindBlock(R(^block)(A1, A2)) {
- return base::Bind(&base::internal::RunBlock<R, A1, A2>,
- base::mac::ScopedBlock<R(^)(A1, A2)>(Block_copy(block)));
+// Construct a callback from an objective-C block with up to six arguments (see
+// note above).
+template<typename R, typename... Args>
+base::Callback<R(Args...)> BindBlock(R(^block)(Args...)) {
+ return base::Bind(&base::internal::RunBlock<R, Args...>,
+ base::mac::ScopedBlock<R(^)(Args...)>(Block_copy(block)));
}
} // namespace base
diff --git a/mac/bind_objc_block_unittest.mm b/mac/bind_objc_block_unittest.mm
index c72fd4a..5d15eba 100644
--- a/mac/bind_objc_block_unittest.mm
+++ b/mac/bind_objc_block_unittest.mm
@@ -64,4 +64,36 @@
EXPECT_EQ(result, "fortytwo");
}
+TEST(BindObjcBlockTest, TestThreeArguments) {
+ std::string result;
+ std::string* ptr = &result;
+ base::Callback<void(const std::string&,
+ const std::string&,
+ const std::string&)> c =
+ base::BindBlock(^(const std::string& a,
+ const std::string& b,
+ const std::string& c) {
+ *ptr = a + b + c;
+ });
+ c.Run("six", "times", "nine");
+ EXPECT_EQ(result, "sixtimesnine");
+}
+
+TEST(BindObjcBlockTest, TestSixArguments) {
+ std::string result1;
+ std::string* ptr = &result1;
+ int result2;
+ int* ptr2 = &result2;
+ base::Callback<void(int, int, const std::string&, const std::string&,
+ int, const std::string&)> c =
+ base::BindBlock(^(int a, int b, const std::string& c,
+ const std::string& d, int e, const std::string& f) {
+ *ptr = c + d + f;
+ *ptr2 = a + b + e;
+ });
+ c.Run(1, 2, "infinite", "improbability", 3, "drive");
+ EXPECT_EQ(result1, "infiniteimprobabilitydrive");
+ EXPECT_EQ(result2, 6);
+}
+
} // namespace
diff --git a/memory/scoped_ptr_unittest.cc b/memory/scoped_ptr_unittest.cc
index 3f169a7..ca7cfbf 100644
--- a/memory/scoped_ptr_unittest.cc
+++ b/memory/scoped_ptr_unittest.cc
@@ -669,7 +669,9 @@
TEST(ScopedPtrTest, SelfResetWithCustomDeleterOptOut) {
// A custom deleter should be able to opt out of self-reset abort behavior.
struct NoOpDeleter {
+#if !defined(NDEBUG)
typedef void AllowSelfReset;
+#endif
inline void operator()(int*) {}
};
scoped_ptr<int> owner(new int);
diff --git a/message_loop/message_loop.cc b/message_loop/message_loop.cc
index 01402d0..2f4a03c 100644
--- a/message_loop/message_loop.cc
+++ b/message_loop/message_loop.cc
@@ -106,9 +106,11 @@
typedef MessagePumpLibevent MessagePumpForIO;
#endif
+#if !defined(OS_NACL_SFI)
MessagePumpForIO* ToPumpIO(MessagePump* pump) {
return static_cast<MessagePumpForIO*>(pump);
}
+#endif // !defined(OS_NACL_SFI)
} // namespace
diff --git a/metrics/histogram.h b/metrics/histogram.h
index 5ed9d9e..43e7462 100644
--- a/metrics/histogram.h
+++ b/metrics/histogram.h
@@ -286,7 +286,7 @@
base::HistogramBase::kUmaTargetedHistogramFlag))
// The samples should always be strictly less than |boundary_value|. For more
-// details, see the comment for the |HISTOGRAM_ENUMERATION| macro, above.
+// details, see the comment for the |LOCAL_HISTOGRAM_ENUMERATION| macro, above.
#define UMA_HISTOGRAM_ENUMERATION(name, sample, boundary_value) \
HISTOGRAM_ENUMERATION_WITH_FLAG(name, sample, boundary_value, \
base::HistogramBase::kUmaTargetedHistogramFlag)
diff --git a/observer_list.h b/observer_list.h
index c77ec15..ef45269 100644
--- a/observer_list.h
+++ b/observer_list.h
@@ -100,7 +100,8 @@
// Remove an observer from the list if it is in the list.
void RemoveObserver(ObserverType* obs);
- bool HasObserver(ObserverType* observer) const;
+ // Determine whether a particular observer is in the list.
+ bool HasObserver(const ObserverType* observer) const;
void Clear();
@@ -176,7 +177,8 @@
}
template <class ObserverType>
-bool ObserverListBase<ObserverType>::HasObserver(ObserverType* observer) const {
+bool ObserverListBase<ObserverType>::HasObserver(
+ const ObserverType* observer) const {
for (size_t i = 0; i < observers_.size(); ++i) {
if (observers_[i] == observer)
return true;
diff --git a/observer_list_unittest.cc b/observer_list_unittest.cc
index 11f59be..65ef934 100644
--- a/observer_list_unittest.cc
+++ b/observer_list_unittest.cc
@@ -182,6 +182,9 @@
observer_list.AddObserver(&a);
observer_list.AddObserver(&b);
+ EXPECT_TRUE(observer_list.HasObserver(&a));
+ EXPECT_FALSE(observer_list.HasObserver(&c));
+
FOR_EACH_OBSERVER(Foo, observer_list, Observe(10));
observer_list.AddObserver(&evil);
diff --git a/profiler/scoped_profile.cc b/profiler/scoped_profile.cc
index 8b0ae59..4f8bc2d 100644
--- a/profiler/scoped_profile.cc
+++ b/profiler/scoped_profile.cc
@@ -11,15 +11,6 @@
namespace tracked_objects {
-ScopedProfile::ScopedProfile(const Location& location)
- : birth_(ThreadData::TallyABirthIfActive(location)) {
- if (!birth_)
- return;
-
- ThreadData::PrepareForStartOfRun(birth_);
- stopwatch_.Start();
-}
-
ScopedProfile::ScopedProfile(const Location& location, Mode mode)
: birth_(NULL) {
if (mode == DISABLED)
diff --git a/profiler/scoped_profile.h b/profiler/scoped_profile.h
index 6a76486..c1e2830 100644
--- a/profiler/scoped_profile.h
+++ b/profiler/scoped_profile.h
@@ -25,10 +25,10 @@
// Defines the containing scope as a profiled region. This allows developers to
// profile their code and see results on their about:profiler page, as well as
// on the UMA dashboard.
-#define TRACK_RUN_IN_THIS_SCOPED_REGION(dispatch_function_name) \
- ::tracked_objects::ScopedProfile LINE_BASED_VARIABLE_NAME_FOR_PROFILING( \
- FROM_HERE_WITH_EXPLICIT_FUNCTION(#dispatch_function_name))
-
+#define TRACK_RUN_IN_THIS_SCOPED_REGION(dispatch_function_name) \
+ ::tracked_objects::ScopedProfile LINE_BASED_VARIABLE_NAME_FOR_PROFILING( \
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(#dispatch_function_name), \
+ ::tracked_objects::ScopedProfile::ENABLED)
namespace tracked_objects {
class Births;
@@ -42,8 +42,6 @@
ENABLED // Create and tally a task.
};
- // TODO(vadimt): Remove this constructor.
- explicit ScopedProfile(const Location& location);
ScopedProfile(const Location& location, Mode mode);
~ScopedProfile();
diff --git a/profiler/scoped_tracker.cc b/profiler/scoped_tracker.cc
index 1d4f0bf..26b17c0 100644
--- a/profiler/scoped_tracker.cc
+++ b/profiler/scoped_tracker.cc
@@ -15,7 +15,7 @@
// Executes |callback|, augmenting it with provided |location|.
void ExecuteAndTrackCallback(const Location& location,
const base::Closure& callback) {
- ScopedProfile tracking_profile(location);
+ ScopedProfile tracking_profile(location, ScopedProfile::ENABLED);
callback.Run();
}
diff --git a/test/launcher/unit_test_launcher.cc b/test/launcher/unit_test_launcher.cc
index 44846a1..a49e777 100644
--- a/test/launcher/unit_test_launcher.cc
+++ b/test/launcher/unit_test_launcher.cc
@@ -479,15 +479,6 @@
fflush(stdout);
force_single_process = true;
}
-
- if (RunningOnValgrind()) {
- fprintf(stdout,
- "Valgrind detected, switching to single process mode.\n"
- "Pass --test-launcher-debug-launcher to valgrind the launcher "
- "itself.\n");
- fflush(stdout);
- force_single_process = true;
- }
}
if (CommandLine::ForCurrentProcess()->HasSwitch(kGTestHelpFlag) ||
diff --git a/threading/platform_thread_linux.cc b/threading/platform_thread_linux.cc
index d9e2bd9..d97a3f4 100644
--- a/threading/platform_thread_linux.cc
+++ b/threading/platform_thread_linux.cc
@@ -27,6 +27,7 @@
namespace {
+#if !defined(OS_NACL)
int ThreadNiceValue(ThreadPriority priority) {
switch (priority) {
case kThreadPriority_RealtimeAudio:
@@ -42,6 +43,7 @@
return 0;
}
}
+#endif // !defined(OS_NACL)
} // namespace
diff --git a/time/time.h b/time/time.h
index 641f465..9cb007e 100644
--- a/time/time.h
+++ b/time/time.h
@@ -232,6 +232,10 @@
static const int64 kNanosecondsPerSecond = kNanosecondsPerMicrosecond *
kMicrosecondsPerSecond;
+ // The representation of Jan 1, 1970 UTC in microseconds since the
+ // platform-dependent epoch.
+ static const int64 kTimeTToMicrosecondsOffset;
+
#if !defined(OS_WIN)
// On Mac & Linux, this value is the delta from the Windows epoch of 1601 to
// the Posix delta of 1970. This is used for migrating between the old
@@ -492,10 +496,6 @@
bool is_local,
Time* parsed_time);
- // The representation of Jan 1, 1970 UTC in microseconds since the
- // platform-dependent epoch.
- static const int64 kTimeTToMicrosecondsOffset;
-
// Time in microseconds in UTC.
int64 us_;
};
diff --git a/tracked_objects.cc b/tracked_objects.cc
index c69fada..5e30762 100644
--- a/tracked_objects.cc
+++ b/tracked_objects.cc
@@ -116,7 +116,7 @@
void DeathData::RecordDeath(const int32 queue_duration,
const int32 run_duration,
- int32 random_number) {
+ const uint32 random_number) {
// We'll just clamp at INT_MAX, but we should note this in the UI as such.
if (count_ < INT_MAX)
++count_;
@@ -307,7 +307,7 @@
(void)VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE(&random_number_,
sizeof(random_number_));
MSAN_UNPOISON(&random_number_, sizeof(random_number_));
- random_number_ += static_cast<int32>(this - static_cast<ThreadData*>(0));
+ random_number_ += static_cast<uint32>(this - static_cast<ThreadData*>(0));
random_number_ ^= (Now() - TrackedTime()).InMilliseconds();
DCHECK(!next_);
@@ -453,10 +453,10 @@
int32 run_duration = stopwatch.RunDurationMs();
// Stir in some randomness, plus add constant in case durations are zero.
- const int32 kSomePrimeNumber = 2147483647;
+ const uint32 kSomePrimeNumber = 2147483647;
random_number_ += queue_duration + run_duration + kSomePrimeNumber;
// An address is going to have some randomness to it as well ;-).
- random_number_ ^= static_cast<int32>(&birth - reinterpret_cast<Births*>(0));
+ random_number_ ^= static_cast<uint32>(&birth - reinterpret_cast<Births*>(0));
// We don't have queue durations without OS timer. OS timer is automatically
// used for task-post-timing, so the use of an alternate timer implies all
diff --git a/tracked_objects.h b/tracked_objects.h
index 50bea47..723fb91 100644
--- a/tracked_objects.h
+++ b/tracked_objects.h
@@ -273,7 +273,7 @@
// |duration|, and has had a queueing delay of |queue_duration|.
void RecordDeath(const int32 queue_duration,
const int32 run_duration,
- int random_number);
+ const uint32 random_number);
// Metrics accessors, used only for serialization and in tests.
int count() const;
@@ -685,7 +685,7 @@
// representative sample in each DeathData instance. We can't start off with
// much randomness (because we can't call RandInt() on all our threads), so
// we stir in more and more as we go.
- int32 random_number_;
+ uint32 random_number_;
// Record of what the incarnation_counter_ was when this instance was created.
// If the incarnation_counter_ has changed, then we avoid pushing into the
diff --git a/win/scoped_comptr_unittest.cc b/win/scoped_comptr_unittest.cc
index d8d12be..711c52f 100644
--- a/win/scoped_comptr_unittest.cc
+++ b/win/scoped_comptr_unittest.cc
@@ -41,8 +41,8 @@
EXPECT_TRUE(SUCCEEDED(unk.CreateInstance(CLSID_ShellLink)));
ScopedComPtr<IUnknown> unk2;
unk2.Attach(unk.Detach());
- EXPECT_TRUE(unk == NULL);
- EXPECT_TRUE(unk2 != NULL);
+ EXPECT_TRUE(unk.get() == NULL);
+ EXPECT_TRUE(unk2.get() != NULL);
ScopedComPtr<IMalloc> mem_alloc;
EXPECT_TRUE(SUCCEEDED(CoGetMalloc(1, mem_alloc.Receive())));
@@ -55,26 +55,26 @@
// test ScopedComPtr& constructor
ScopedComPtr<IMalloc> copy1(mem_alloc);
- EXPECT_TRUE(copy1.IsSameObject(mem_alloc));
- EXPECT_FALSE(copy1.IsSameObject(unk2)); // unk2 is valid but different
- EXPECT_FALSE(copy1.IsSameObject(unk)); // unk is NULL
+ EXPECT_TRUE(copy1.IsSameObject(mem_alloc.get()));
+ EXPECT_FALSE(copy1.IsSameObject(unk2.get())); // unk2 is valid but different
+ EXPECT_FALSE(copy1.IsSameObject(unk.get())); // unk is NULL
IMalloc* naked_copy = copy1.Detach();
copy1 = naked_copy; // Test the =(T*) operator.
naked_copy->Release();
copy1.Release();
- EXPECT_FALSE(copy1.IsSameObject(unk2)); // unk2 is valid, copy1 is not
+ EXPECT_FALSE(copy1.IsSameObject(unk2.get())); // unk2 is valid, copy1 is not
// test Interface* constructor
- ScopedComPtr<IMalloc> copy2(static_cast<IMalloc*>(mem_alloc));
- EXPECT_TRUE(copy2.IsSameObject(mem_alloc));
+ ScopedComPtr<IMalloc> copy2(static_cast<IMalloc*>(mem_alloc.get()));
+ EXPECT_TRUE(copy2.IsSameObject(mem_alloc.get()));
- EXPECT_TRUE(SUCCEEDED(unk.QueryFrom(mem_alloc)));
- EXPECT_TRUE(unk != NULL);
+ EXPECT_TRUE(SUCCEEDED(unk.QueryFrom(mem_alloc.get())));
+ EXPECT_TRUE(unk.get() != NULL);
unk.Release();
- EXPECT_TRUE(unk == NULL);
- EXPECT_TRUE(unk.IsSameObject(copy1)); // both are NULL
+ EXPECT_TRUE(unk.get() == NULL);
+ EXPECT_TRUE(unk.IsSameObject(copy1.get())); // both are NULL
}
TEST(ScopedComPtrTest, ScopedComPtrVector) {
@@ -98,7 +98,7 @@
bleh.push_back(p2);
EXPECT_EQ(p->adds, 4);
EXPECT_EQ(p->releases, 1);
- EXPECT_EQ(bleh[0], p.get());
+ EXPECT_EQ(bleh[0].get(), p.get());
bleh.pop_back();
EXPECT_EQ(p->adds, 4);
EXPECT_EQ(p->releases, 2);