GitHub

@@ -2786,7 +2786,7 @@ const artQuickCodeReplacementTrampolineWriters = {

27862786

arm64: writeArtQuickCodeReplacementTrampolineArm64

27872787

};

278827882789-

function writeArtQuickCodeReplacementTrampolineIA32 (trampoline, target, redirectSize, vm) {

2789+

function writeArtQuickCodeReplacementTrampolineIA32 (trampoline, target, redirectSize, constraints, vm) {

27902790

const threadOffsets = getArtThreadSpec(vm).offset;

27912791

const artMethodOffsets = getArtMethodSpec(vm).offset;

27922792

@@ -2849,7 +2849,7 @@ function writeArtQuickCodeReplacementTrampolineIA32 (trampoline, target, redirec

28492849

return offset;

28502850

}

285128512852-

function writeArtQuickCodeReplacementTrampolineX64 (trampoline, target, redirectSize, vm) {

2852+

function writeArtQuickCodeReplacementTrampolineX64 (trampoline, target, redirectSize, constraints, vm) {

28532853

const threadOffsets = getArtThreadSpec(vm).offset;

28542854

const artMethodOffsets = getArtMethodSpec(vm).offset;

28552855

@@ -2912,7 +2912,7 @@ function writeArtQuickCodeReplacementTrampolineX64 (trampoline, target, redirect

29122912

return offset;

29132913

}

291429142915-

function writeArtQuickCodeReplacementTrampolineArm (trampoline, target, redirectSize, vm) {

2915+

function writeArtQuickCodeReplacementTrampolineArm (trampoline, target, redirectSize, constraints, vm) {

29162916

const artMethodOffsets = getArtMethodSpec(vm).offset;

2917291729182918

const targetAddress = target.and(THUMB_BIT_REMOVAL_MASK);

@@ -2999,7 +2999,7 @@ function writeArtQuickCodeReplacementTrampolineArm (trampoline, target, redirect

29992999

return offset;

30003000

}

300130013002-

function writeArtQuickCodeReplacementTrampolineArm64 (trampoline, target, redirectSize, vm) {

3002+

function writeArtQuickCodeReplacementTrampolineArm64 (trampoline, target, redirectSize, { availableScratchRegs }, vm) {

30033003

const artMethodOffsets = getArtMethodSpec(vm).offset;

3004300430053005

let offset;

@@ -3068,8 +3068,9 @@ function writeArtQuickCodeReplacementTrampolineArm64 (trampoline, target, redire

30683068

relocator.writeAll();

3069306930703070

if (!relocator.eoi) {

3071-

writer.putLdrRegAddress('x17', target.add(offset));

3072-

writer.putBrReg('x17');

3071+

const scratchReg = Array.from(availableScratchRegs)[0];

3072+

writer.putLdrRegAddress(scratchReg, target.add(offset));

3073+

writer.putBrReg(scratchReg);

30733074

}

3074307530753076

writer.putLabel('invoke_replacement');

@@ -3146,7 +3147,7 @@ class ArtQuickCodeInterceptor {

31463147

this.overwrittenPrologueLength = 0;

31473148

}

314831493149-

_canRelocateCode (relocationSize) {

3150+

_canRelocateCode (relocationSize, constraints) {

31503151

const Writer = thunkWriters[Process.arch];

31513152

const Relocator = thunkRelocators[Process.arch];

31523153

@@ -3156,14 +3157,44 @@ class ArtQuickCodeInterceptor {

31563157

const relocator = new Relocator(quickCodeAddress, writer);

3157315831583159

let offset;

3159-

do {

3160-

offset = relocator.readOne();

3161-

} while (offset < relocationSize && !relocator.eoi);

3160+

if (Process.arch === 'arm64') {

3161+

let availableScratchRegs = new Set(['x16', 'x17']);

3162+3163+

do {

3164+

const nextOffset = relocator.readOne();

3165+3166+

const nextScratchRegs = new Set(availableScratchRegs);

3167+

const { read, written } = relocator.input.regsAccessed;

3168+

for (const regs of [read, written]) {

3169+

for (const reg of regs) {

3170+

let name;

3171+

if (reg.startsWith('w')) {

3172+

name = 'x' + reg.substring(1);

3173+

} else {

3174+

name = reg;

3175+

}

3176+

nextScratchRegs.delete(name);

3177+

}

3178+

}

3179+

if (nextScratchRegs.size === 0) {

3180+

break;

3181+

}

3182+3183+

offset = nextOffset;

3184+

availableScratchRegs = nextScratchRegs;

3185+

} while (offset < relocationSize && !relocator.eoi);

3186+3187+

constraints.availableScratchRegs = availableScratchRegs;

3188+

} else {

3189+

do {

3190+

offset = relocator.readOne();

3191+

} while (offset < relocationSize && !relocator.eoi);

3192+

}

3162319331633194

return offset >= relocationSize;

31643195

}

316531963166-

_createTrampoline () {

3197+

_allocateTrampoline () {

31673198

if (trampolineAllocator === null) {

31683199

const trampolineSize = (pointerSize === 4) ? 128 : 256;

31693200

trampolineAllocator = makeCodeAllocator(trampolineSize);

@@ -3173,7 +3204,8 @@ class ArtQuickCodeInterceptor {

3173320431743205

let redirectSize, spec;

31753206

let alignment = 1;

3176-

if (pointerSize === 4 || this._canRelocateCode(maxRedirectSize)) {

3207+

const constraints = {};

3208+

if (pointerSize === 4 || this._canRelocateCode(maxRedirectSize, constraints)) {

31773209

redirectSize = maxRedirectSize;

3178321031793211

spec = {};

@@ -3193,19 +3225,21 @@ class ArtQuickCodeInterceptor {

3193322531943226

this.redirectSize = redirectSize;

31953227

this.trampoline = trampolineAllocator.allocateSlice(spec, alignment);

3228+3229+

return constraints;

31963230

}

3197323131983232

_destroyTrampoline () {

31993233

trampolineAllocator.freeSlice(this.trampoline);

32003234

}

3201323532023236

activate (vm) {

3203-

this._createTrampoline();

3237+

const constraints = this._allocateTrampoline();

3204323832053239

const { trampoline, quickCode, redirectSize } = this;

3206324032073241

const writeTrampoline = artQuickCodeReplacementTrampolineWriters[Process.arch];

3208-

const prologueLength = writeTrampoline(trampoline, quickCode, redirectSize, vm);

3242+

const prologueLength = writeTrampoline(trampoline, quickCode, redirectSize, constraints, vm);

32093243

this.overwrittenPrologueLength = prologueLength;

3210324432113245

this.overwrittenPrologue = Memory.dup(this.quickCodeAddress, prologueLength);

Read the original on github.com ↗