Log Message
Put g_gigacageBasePtr into its own page and make it read-only https://bugs.webkit.org/show_bug.cgi?id=174972
Reviewed by Michael Saboff.
Source/bmalloc:
This puts the gigacage base pointers into their own page and makes that page read-only.
* bmalloc/Gigacage.cpp:
(Gigacage::ensureGigacage):
(Gigacage::disablePrimitiveGigacage):
(Gigacage::addPrimitiveDisableCallback):
* bmalloc/Gigacage.h:
(Gigacage::basePtr):
(Gigacage::basePtrs):
Source/_javascript_Core:
C++ code doesn't have to know about this change. That includes C++ code that generates JIT code.
But the offline assembler now needs to know about how to load from offsets of global variables.
This turned out to be easy to support by extending the existing _expression_ support.
* llint/LowLevelInterpreter64.asm:
* offlineasm/ast.rb:
* offlineasm/parser.rb:
* offlineasm/transform.rb:
* offlineasm/x86.rb:
Modified Paths
- trunk/Source/_javascript_Core/ChangeLog
- trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm
- trunk/Source/_javascript_Core/offlineasm/ast.rb
- trunk/Source/_javascript_Core/offlineasm/parser.rb
- trunk/Source/_javascript_Core/offlineasm/transform.rb
- trunk/Source/_javascript_Core/offlineasm/x86.rb
- trunk/Source/bmalloc/ChangeLog
- trunk/Source/bmalloc/bmalloc/Gigacage.cpp
- trunk/Source/bmalloc/bmalloc/Gigacage.h
Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (222548 => 222549)
--- trunk/Source/_javascript_Core/ChangeLog 2017-09-27 03:17:31 UTC (rev 222548)
+++ trunk/Source/_javascript_Core/ChangeLog 2017-09-27 05:05:27 UTC (rev 222549)
@@ -1,3 +1,21 @@
+2017-09-26 Filip Pizlo <[email protected]>
+
+ Put g_gigacageBasePtr into its own page and make it read-only
+ https://bugs.webkit.org/show_bug.cgi?id=174972
+
+ Reviewed by Michael Saboff.
+
+ C++ code doesn't have to know about this change. That includes C++ code that generates JIT code.
+
+ But the offline assembler now needs to know about how to load from offsets of global variables.
+ This turned out to be easy to support by extending the existing _expression_ support.
+
+ * llint/LowLevelInterpreter64.asm:
+ * offlineasm/ast.rb:
+ * offlineasm/parser.rb:
+ * offlineasm/transform.rb:
+ * offlineasm/x86.rb:
+
2017-09-26 Commit Queue <[email protected]>
Unreviewed, rolling out r222518.
Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm (222548 => 222549)
--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm 2017-09-27 03:17:31 UTC (rev 222548)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm 2017-09-27 05:05:27 UTC (rev 222549)
@@ -1209,7 +1209,7 @@
macro loadPropertyAtVariableOffset(propertyOffsetAsInt, objectAndStorage, value)
bilt propertyOffsetAsInt, firstOutOfLineOffset, .isInline
- loadCaged(_g_jsValueGigacageBasePtr, constexpr JSVALUE_GIGACAGE_MASK, JSObject::m_butterfly[objectAndStorage], objectAndStorage, value)
+ loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::jsValue, constexpr JSVALUE_GIGACAGE_MASK, JSObject::m_butterfly[objectAndStorage], objectAndStorage, value)
negi propertyOffsetAsInt
sxi2q propertyOffsetAsInt, propertyOffsetAsInt
jmp .ready
@@ -1222,7 +1222,7 @@
macro storePropertyAtVariableOffset(propertyOffsetAsInt, objectAndStorage, value, scratch)
bilt propertyOffsetAsInt, firstOutOfLineOffset, .isInline
- loadCaged(_g_jsValueGigacageBasePtr, constexpr JSVALUE_GIGACAGE_MASK, JSObject::m_butterfly[objectAndStorage], objectAndStorage, scratch)
+ loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::jsValue, constexpr JSVALUE_GIGACAGE_MASK, JSObject::m_butterfly[objectAndStorage], objectAndStorage, scratch)
negi propertyOffsetAsInt
sxi2q propertyOffsetAsInt, propertyOffsetAsInt
jmp .ready
@@ -1298,7 +1298,7 @@
btiz t2, IsArray, .opGetArrayLengthSlow
btiz t2, IndexingShapeMask, .opGetArrayLengthSlow
loadisFromInstruction(1, t1)
- loadCaged(_g_jsValueGigacageBasePtr, constexpr JSVALUE_GIGACAGE_MASK, JSObject::m_butterfly[t3], t0, t2)
+ loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::jsValue, constexpr JSVALUE_GIGACAGE_MASK, JSObject::m_butterfly[t3], t0, t2)
loadi -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], t0
bilt t0, 0, .opGetArrayLengthSlow
orq tagTypeNumber, t0
@@ -1481,7 +1481,7 @@
loadisFromInstruction(3, t3)
loadConstantOrVariableInt32(t3, t1, .opGetByValSlow)
sxi2q t1, t1
- loadCaged(_g_jsValueGigacageBasePtr, constexpr JSVALUE_GIGACAGE_MASK, JSObject::m_butterfly[t0], t3, t5)
+ loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::jsValue, constexpr JSVALUE_GIGACAGE_MASK, JSObject::m_butterfly[t0], t3, t5)
andi IndexingShapeMask, t2
bieq t2, Int32Shape, .opGetByValIsContiguous
bineq t2, ContiguousShape, .opGetByValNotContiguous
@@ -1528,7 +1528,7 @@
bia t2, LastArrayType - FirstArrayType, .opGetByValSlow
# Sweet, now we know that we have a typed array. Do some basic things now.
- loadCaged(_g_primitiveGigacageBasePtr, constexpr PRIMITIVE_GIGACAGE_MASK, JSArrayBufferView::m_vector[t0], t3, t5)
+ loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr PRIMITIVE_GIGACAGE_MASK, JSArrayBufferView::m_vector[t0], t3, t5)
biaeq t1, JSArrayBufferView::m_length[t0], .opGetByValSlow
# Now bisect through the various types. Note that we can treat Uint8ArrayType and
@@ -1619,7 +1619,7 @@
loadisFromInstruction(2, t0)
loadConstantOrVariableInt32(t0, t3, .opPutByValSlow)
sxi2q t3, t3
- loadCaged(_g_jsValueGigacageBasePtr, constexpr JSVALUE_GIGACAGE_MASK, JSObject::m_butterfly[t1], t0, t5)
+ loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::jsValue, constexpr JSVALUE_GIGACAGE_MASK, JSObject::m_butterfly[t1], t0, t5)
andi IndexingShapeMask, t2
bineq t2, Int32Shape, .opPutByValNotInt32
contiguousPutByVal(
Modified: trunk/Source/_javascript_Core/offlineasm/ast.rb (222548 => 222549)
--- trunk/Source/_javascript_Core/offlineasm/ast.rb 2017-09-27 03:17:31 UTC (rev 222548)
+++ trunk/Source/_javascript_Core/offlineasm/ast.rb 2017-09-27 05:05:27 UTC (rev 222549)
@@ -1110,12 +1110,20 @@
class LabelReference < Node
attr_reader :label
+ attr_accessor :offset
def initialize(codeOrigin, label)
super(codeOrigin)
@label = label
+ @offset = 0
end
+ def plusOffset(additionalOffset)
+ result = LabelReference.new(codeOrigin, label)
+ result.offset = @offset + additionalOffset
+ result
+ end
+
def children
[@label]
end
Modified: trunk/Source/_javascript_Core/offlineasm/parser.rb (222548 => 222549)
--- trunk/Source/_javascript_Core/offlineasm/parser.rb 2017-09-27 03:17:31 UTC (rev 222548)
+++ trunk/Source/_javascript_Core/offlineasm/parser.rb 2017-09-27 05:05:27 UTC (rev 222549)
@@ -516,7 +516,7 @@
end
def couldBeExpression
- @tokens[@idx] == "-" or @tokens[@idx] == "~" or @tokens[@idx] == "sizeof" or @tokens[@idx] == "constexpr" or isInteger(@tokens[@idx]) or isString(@tokens[@idx]) or isVariable(@tokens[@idx]) or @tokens[@idx] == "("
+ @tokens[@idx] == "-" or @tokens[@idx] == "~" or @tokens[@idx] == "sizeof" or @tokens[@idx] == "constexpr" or isInteger(@tokens[@idx]) or isString(@tokens[@idx]) or isVariable(@tokens[@idx]) or isLabel(@tokens[@idx]) or @tokens[@idx] == "("
end
def parseExpressionAdd
@@ -574,10 +574,6 @@
end
elsif @tokens[@idx] == "["
parseAddress(Immediate.new(@tokens[@idx].codeOrigin, 0))
- elsif isLabel @tokens[@idx]
- result = LabelReference.new(@tokens[@idx].codeOrigin, Label.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string))
- @idx += 1
- result
elsif isLocalLabel @tokens[@idx]
result = LocalLabelReference.new(@tokens[@idx].codeOrigin, LocalLabel.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string))
@idx += 1
Modified: trunk/Source/_javascript_Core/offlineasm/transform.rb (222548 => 222549)
--- trunk/Source/_javascript_Core/offlineasm/transform.rb 2017-09-27 03:17:31 UTC (rev 222548)
+++ trunk/Source/_javascript_Core/offlineasm/transform.rb 2017-09-27 05:05:27 UTC (rev 222549)
@@ -312,6 +312,10 @@
def fold
@left = @left.fold
@right = @right.fold
+
+ return right.plusOffset(@left.value) if @left.is_a? Immediate and @right.is_a? LabelReference
+ return left.plusOffset(@right.value) if @left.is_a? LabelReference and @right.is_a? Immediate
+
return self unless @left.is_a? Immediate
return self unless @right.is_a? Immediate
Immediate.new(codeOrigin, @left.value + @right.value)
@@ -322,6 +326,9 @@
def fold
@left = @left.fold
@right = @right.fold
+
+ return left.plusOffset([email protected]) if @left.is_a? LabelReference and @right.is_a? Immediate
+
return self unless @left.is_a? Immediate
return self unless @right.is_a? Immediate
Immediate.new(codeOrigin, @left.value - @right.value)
Modified: trunk/Source/_javascript_Core/offlineasm/x86.rb (222548 => 222549)
--- trunk/Source/_javascript_Core/offlineasm/x86.rb 2017-09-27 03:17:31 UTC (rev 222548)
+++ trunk/Source/_javascript_Core/offlineasm/x86.rb 2017-09-27 05:05:27 UTC (rev 222549)
@@ -466,7 +466,7 @@
# FIXME: Implement this on platforms that aren't Mach-O.
# https://bugs.webkit.org/show_bug.cgi?id=175104
$asm.puts "movq #{asmLabel}@GOTPCREL(%rip), #{dst.x86Operand(:ptr)}"
- "(#{dst.x86Operand(kind)})"
+ "#{offset}(#{dst.x86Operand(kind)})"
end
end
Modified: trunk/Source/bmalloc/ChangeLog (222548 => 222549)
--- trunk/Source/bmalloc/ChangeLog 2017-09-27 03:17:31 UTC (rev 222548)
+++ trunk/Source/bmalloc/ChangeLog 2017-09-27 05:05:27 UTC (rev 222549)
@@ -1,3 +1,20 @@
+2017-09-26 Filip Pizlo <[email protected]>
+
+ Put g_gigacageBasePtr into its own page and make it read-only
+ https://bugs.webkit.org/show_bug.cgi?id=174972
+
+ Reviewed by Michael Saboff.
+
+ This puts the gigacage base pointers into their own page and makes that page read-only.
+
+ * bmalloc/Gigacage.cpp:
+ (Gigacage::ensureGigacage):
+ (Gigacage::disablePrimitiveGigacage):
+ (Gigacage::addPrimitiveDisableCallback):
+ * bmalloc/Gigacage.h:
+ (Gigacage::basePtr):
+ (Gigacage::basePtrs):
+
2017-09-04 Adrian Perez de Castro <[email protected]>
Unreviewed build fix for Clang with libc++
Modified: trunk/Source/bmalloc/bmalloc/Gigacage.cpp (222548 => 222549)
--- trunk/Source/bmalloc/bmalloc/Gigacage.cpp 2017-09-27 03:17:31 UTC (rev 222548)
+++ trunk/Source/bmalloc/bmalloc/Gigacage.cpp 2017-09-27 05:05:27 UTC (rev 222549)
@@ -33,18 +33,44 @@
#include <cstdio>
#include <mutex>
-// FIXME: Ask dyld to put this in its own page, and mprotect the page after we ensure the gigacage.
-// https://bugs.webkit.org/show_bug.cgi?id=174972
-void* g_primitiveGigacageBasePtr;
-void* g_jsValueGigacageBasePtr;
-void* g_stringGigacageBasePtr;
+char g_gigacageBasePtrs[GIGACAGE_BASE_PTRS_SIZE] __attribute__((aligned(GIGACAGE_BASE_PTRS_SIZE)));
using namespace bmalloc;
namespace Gigacage {
-static bool s_isDisablingPrimitiveGigacageDisabled;
+namespace {
+bool s_isDisablingPrimitiveGigacageDisabled;
+
+void protectGigacageBasePtrs()
+{
+ uintptr_t basePtrs = reinterpret_cast<uintptr_t>(g_gigacageBasePtrs);
+ // We might only get page size alignment, but that's also the minimum we need.
+ RELEASE_BASSERT(!(basePtrs & (vmPageSize() - 1)));
+ mprotect(g_gigacageBasePtrs, GIGACAGE_BASE_PTRS_SIZE, PROT_READ);
+}
+
+void unprotectGigacageBasePtrs()
+{
+ mprotect(g_gigacageBasePtrs, GIGACAGE_BASE_PTRS_SIZE, PROT_READ | PROT_WRITE);
+}
+
+class UnprotectGigacageBasePtrsScope {
+public:
+ UnprotectGigacageBasePtrsScope()
+ {
+ unprotectGigacageBasePtrs();
+ }
+
+ ~UnprotectGigacageBasePtrsScope()
+ {
+ protectGigacageBasePtrs();
+ }
+};
+
+} // anonymous namespce
+
struct Callback {
Callback() { }
@@ -86,6 +112,8 @@
vmDeallocatePhysicalPages(basePtr(kind), totalSize(kind));
});
+
+ protectGigacageBasePtrs();
});
#endif // GIGACAGE_ENABLED
}
@@ -93,7 +121,7 @@
void disablePrimitiveGigacage()
{
ensureGigacage();
- if (!g_primitiveGigacageBasePtr) {
+ if (!basePtrs().primitive) {
// It was never enabled. That means that we never even saved any callbacks. Or, we had already disabled
// it before, and already called the callbacks.
return;
@@ -104,13 +132,14 @@
for (Callback& callback : callbacks.callbacks)
callback.function(callback.argument);
callbacks.callbacks.shrink(0);
- g_primitiveGigacageBasePtr = nullptr;
+ UnprotectGigacageBasePtrsScope unprotectScope;
+ basePtrs().primitive = nullptr;
}
void addPrimitiveDisableCallback(void (*function)(void*), void* argument)
{
ensureGigacage();
- if (!g_primitiveGigacageBasePtr) {
+ if (!basePtrs().primitive) {
// It was already disabled or we were never able to enable it.
function(argument);
return;
Modified: trunk/Source/bmalloc/bmalloc/Gigacage.h (222548 => 222549)
--- trunk/Source/bmalloc/bmalloc/Gigacage.h 2017-09-27 03:17:31 UTC (rev 222548)
+++ trunk/Source/bmalloc/bmalloc/Gigacage.h 2017-09-27 05:05:27 UTC (rev 222549)
@@ -57,12 +57,18 @@
#define GIGACAGE_ENABLED 0
#endif
-extern "C" BEXPORT void* g_primitiveGigacageBasePtr;
-extern "C" BEXPORT void* g_jsValueGigacageBasePtr;
-extern "C" BEXPORT void* g_stringGigacageBasePtr;
+#define GIGACAGE_BASE_PTRS_SIZE 8192
+extern "C" BEXPORT char g_gigacageBasePtrs[GIGACAGE_BASE_PTRS_SIZE] __attribute__((aligned(GIGACAGE_BASE_PTRS_SIZE)));
+
namespace Gigacage {
+struct BasePtrs {
+ void* primitive;
+ void* jsValue;
+ void* string;
+};
+
enum Kind {
Primitive,
JSValue,
@@ -97,20 +103,30 @@
return nullptr;
}
-BINLINE void*& basePtr(Kind kind)
+BINLINE void*& basePtr(BasePtrs& basePtrs, Kind kind)
{
switch (kind) {
case Primitive:
- return g_primitiveGigacageBasePtr;
+ return basePtrs.primitive;
case JSValue:
- return g_jsValueGigacageBasePtr;
+ return basePtrs.jsValue;
case String:
- return g_stringGigacageBasePtr;
+ return basePtrs.string;
}
BCRASH();
- return g_primitiveGigacageBasePtr;
+ return basePtrs.primitive;
}
+BINLINE BasePtrs& basePtrs()
+{
+ return *reinterpret_cast<BasePtrs*>(g_gigacageBasePtrs);
+}
+
+BINLINE void*& basePtr(Kind kind)
+{
+ return basePtr(basePtrs(), kind);
+}
+
BINLINE size_t size(Kind kind)
{
switch (kind) {
_______________________________________________ webkit-changes mailing list [email protected] https://lists.webkit.org/mailman/listinfo/webkit-changes
