Bug 1414338 - Add some assertions to TraceDataRelocations r=sfink
authorJon Coppeard <jcoppeard@mozilla.com>
Fri, 10 Nov 2017 11:28:38 +0000
changeset 444439 3b3fdb4f8f360be4e0149218ca99f2514a113f77
parent 444438 e73ab24a3204663b97f568820e043e466084a116
child 444440 ab8967c4e3c685649e422acd0dc590710bf0f06a
push id1618
push userCallek@gmail.com
push dateThu, 11 Jan 2018 17:45:48 +0000
treeherdermozilla-release@882ca853e05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs1414338
milestone58.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1414338 - Add some assertions to TraceDataRelocations r=sfink
js/public/HeapAPI.h
js/src/jit/x86-shared/Assembler-x86-shared.cpp
--- a/js/public/HeapAPI.h
+++ b/js/public/HeapAPI.h
@@ -337,17 +337,16 @@ GetGCThingMarkWordAndMask(const uintptr_
 }
 
 static MOZ_ALWAYS_INLINE JS::Zone*
 GetGCThingZone(const uintptr_t addr)
 {
     MOZ_ASSERT(addr);
     const uintptr_t zone_addr = (addr & ~ArenaMask) | ArenaZoneOffset;
     return *reinterpret_cast<JS::Zone**>(zone_addr);
-
 }
 
 static MOZ_ALWAYS_INLINE bool
 TenuredCellIsMarkedGray(const Cell* cell)
 {
     // Return true if GrayOrBlackBit is set and BlackBit is not set.
     MOZ_ASSERT(cell);
     MOZ_ASSERT(!js::gc::IsInsideNursery(cell));
--- a/js/src/jit/x86-shared/Assembler-x86-shared.cpp
+++ b/js/src/jit/x86-shared/Assembler-x86-shared.cpp
@@ -35,68 +35,71 @@ AssemblerX86Shared::copyJumpRelocationTa
 void
 AssemblerX86Shared::copyDataRelocationTable(uint8_t* dest)
 {
     if (dataRelocations_.length())
         memcpy(dest, dataRelocations_.buffer(), dataRelocations_.length());
 }
 
 static void
-TraceDataRelocations(JSTracer* trc, uint8_t* buffer, CompactBufferReader& reader)
+TraceDataRelocations(JSTracer* trc, CompactBufferReader& reader,
+                     uint8_t* buffer, size_t bufferSize)
 {
     while (reader.more()) {
         size_t offset = reader.readUnsigned();
-        void* ptr = X86Encoding::GetPointer(buffer + offset);
+        MOZ_ASSERT(offset >= sizeof(void*) && offset <= bufferSize);
+
+        uint8_t* src = buffer + offset;
+        void* data = X86Encoding::GetPointer(src);
 
 #ifdef JS_PUNBOX64
         // All pointers on x64 will have the top bits cleared. If those bits
         // are not cleared, this must be a Value.
-        uintptr_t word = reinterpret_cast<uintptr_t>(ptr);
+        uintptr_t word = reinterpret_cast<uintptr_t>(data);
         if (word >> JSVAL_TAG_SHIFT) {
-            Value v = Value::fromRawBits(word);
-            TraceManuallyBarrieredEdge(trc, &v, "jit-masm-value");
-            if (word != v.asRawBits()) {
+            Value value = Value::fromRawBits(word);
+            MOZ_ASSERT_IF(value.isGCThing(), gc::IsCellPointerValid(value.toGCThing()));
+            TraceManuallyBarrieredEdge(trc, &value, "jit-masm-value");
+            if (word != value.asRawBits()) {
                 // Only update the code if the Value changed, because the code
                 // is not writable if we're not moving objects.
-                X86Encoding::SetPointer(buffer + offset, v.bitsAsPunboxPointer());
+                X86Encoding::SetPointer(src, value.bitsAsPunboxPointer());
             }
             continue;
         }
 #endif
 
-        // No barrier needed since these are constants.
-        gc::Cell* cellPtr = reinterpret_cast<gc::Cell*>(ptr);
-        TraceManuallyBarrieredGenericPointerEdge(trc, &cellPtr, "jit-masm-ptr");
-        if (cellPtr != ptr)
-            X86Encoding::SetPointer(buffer + offset, cellPtr);
+        gc::Cell* cell = static_cast<gc::Cell*>(data);
+        MOZ_ASSERT(gc::IsCellPointerValid(cell));
+        TraceManuallyBarrieredGenericPointerEdge(trc, &cell, "jit-masm-ptr");
+        if (cell != data)
+            X86Encoding::SetPointer(src, cell);
     }
 }
 
-
 void
 AssemblerX86Shared::TraceDataRelocations(JSTracer* trc, JitCode* code, CompactBufferReader& reader)
 {
-    ::TraceDataRelocations(trc, code->raw(), reader);
+    ::TraceDataRelocations(trc, reader, code->raw(), code->instructionsSize());
 }
 
 void
 AssemblerX86Shared::trace(JSTracer* trc)
 {
     for (size_t i = 0; i < jumps_.length(); i++) {
         RelativePatch& rp = jumps_[i];
         if (rp.kind == Relocation::JITCODE) {
             JitCode* code = JitCode::FromExecutable((uint8_t*)rp.target);
             TraceManuallyBarrieredEdge(trc, &code, "masmrel32");
             MOZ_ASSERT(code == JitCode::FromExecutable((uint8_t*)rp.target));
         }
     }
     if (dataRelocations_.length()) {
         CompactBufferReader reader(dataRelocations_);
-        unsigned char* code = masm.data();
-        ::TraceDataRelocations(trc, code, reader);
+        ::TraceDataRelocations(trc, reader, masm.data(), masm.size());
     }
 }
 
 void
 AssemblerX86Shared::executableCopy(void* buffer)
 {
     masm.executableCopy(buffer);