Bug 831754 part 2 - Add patchable call instruction, x86/x64 part. r=dvander a=nonlibxul
authorJan de Mooij <jdemooij@mozilla.com>
Tue, 22 Jan 2013 14:33:36 +0100
changeset 129356 ef3ed8dd472611be8ccdf85fbcc8926127fb5138
parent 129355 c7b78d418a1e516888187e6ce1501797401cf5c6
child 129357 cec0e9df1d2c936b59b297e6fe20996a6316a6a4
push id2323
push userbbajaj@mozilla.com
push dateMon, 01 Apr 2013 19:47:02 +0000
treeherdermozilla-beta@7712be144d91 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdvander, nonlibxul
bugs831754
milestone21.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 831754 part 2 - Add patchable call instruction, x86/x64 part. r=dvander a=nonlibxul
js/src/ion/shared/Assembler-x86-shared.h
js/src/ion/x64/Assembler-x64.h
js/src/ion/x86/Assembler-x86.h
--- a/js/src/ion/shared/Assembler-x86-shared.h
+++ b/js/src/ion/shared/Assembler-x86-shared.h
@@ -1241,15 +1241,21 @@ class AssemblerX86Shared
         JS_ASSERT(*ptr == 0x3D);
         *ptr = 0xE9;
     }
     static void ToggleToCmp(CodeLocationLabel inst) {
         uint8_t *ptr = (uint8_t *)inst.raw();
         JS_ASSERT(*ptr == 0xE9);
         *ptr = 0x3D;
     }
+    static void ToggleCall(CodeLocationLabel inst, bool enabled) {
+        uint8_t *ptr = (uint8_t *)inst.raw();
+        JS_ASSERT(*ptr == 0x3D || // CMP
+                  *ptr == 0xE8);  // CALL
+        *ptr = enabled ? 0xE8 : 0x3D;
+    }
 };
 
 } // namespace ion
 } // namespace js
 
 #endif // jsion_assembler_x86_shared__
 
--- a/js/src/ion/x64/Assembler-x64.h
+++ b/js/src/ion/x64/Assembler-x64.h
@@ -553,16 +553,25 @@ class Assembler : public AssemblerX86Sha
     void j(Condition cond, IonCode *target) {
         j(cond, target->raw(), Relocation::IONCODE);
     }
     void call(IonCode *target) {
         JmpSrc src = masm.call();
         addPendingJump(src, target->raw(), Relocation::IONCODE);
     }
 
+    // Emit a CALL or CMP (nop) instruction. ToggleCall can be used to patch
+    // this instruction.
+    CodeOffsetLabel toggledCall(IonCode *target, bool enabled) {
+        CodeOffsetLabel offset(size());
+        JmpSrc src = enabled ? masm.call() : masm.cmp_eax();
+        addPendingJump(src, target->raw(), Relocation::IONCODE);
+        return offset;
+    }
+
     // Do not mask shared implementations.
     using AssemblerX86Shared::call;
 
     void cvttsd2sq(const FloatRegister &src, const Register &dest) {
         masm.cvttsd2sq_rr(src.code(), dest.code());
     }
     void cvttsd2s(const FloatRegister &src, const Register &dest) {
         cvttsd2sq(src, dest);
--- a/js/src/ion/x86/Assembler-x86.h
+++ b/js/src/ion/x86/Assembler-x86.h
@@ -364,16 +364,25 @@ class Assembler : public AssemblerX86Sha
         JmpSrc src = masm.call();
         addPendingJump(src, target->raw(), Relocation::IONCODE);
     }
     void call(ImmWord target) {
         JmpSrc src = masm.call();
         addPendingJump(src, target.asPointer(), Relocation::HARDCODED);
     }
 
+    // Emit a CALL or CMP (nop) instruction. ToggleCall can be used to patch
+    // this instruction.
+    CodeOffsetLabel toggledCall(IonCode *target, bool enabled) {
+        CodeOffsetLabel offset(size());
+        JmpSrc src = enabled ? masm.call() : masm.cmp_eax();
+        addPendingJump(src, target->raw(), Relocation::IONCODE);
+        return offset;
+    }
+
     // Re-routes pending jumps to an external target, flushing the label in the
     // process.
     void retarget(Label *label, void *target, Relocation::Kind reloc) {
         JSC::MacroAssembler::Label jsclabel;
         if (label->used()) {
             bool more;
             JSC::X86Assembler::JmpSrc jmp(label->offset());
             do {