Skip to content

Commit 02d5755

Browse files
committed
Bug 1991402 - Part 18: Make ArrayJoinResult a shared CacheIR instruction. r=jandem
Use `AutoCallVM` to move the implementation into `CacheIRCompiler`. Differential Revision: https://phabricator.services.mozilla.com/D266774
1 parent 86d784c commit 02d5755

File tree

5 files changed

+74
-73
lines changed

5 files changed

+74
-73
lines changed

js/src/jit-test/tests/cacheir/inlinable-native-accessor-6.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,13 @@ function testArraySliceArguments() {
5656
}
5757
}
5858
testArraySliceArguments();
59+
60+
function testArrayJoin() {
61+
Object.defineProperty(Array.prototype, "joined", {get: Array.prototype.join});
62+
63+
for (var i = 0; i < 100; ++i) {
64+
assertEq([].joined, "");
65+
assertEq(["a"].joined, "a");
66+
}
67+
}
68+
testArrayJoin();

js/src/jit/BaselineCacheIRCompiler.cpp

Lines changed: 0 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,73 +1040,6 @@ bool BaselineCacheIRCompiler::emitAllocateAndStoreDynamicSlot(
10401040
newShapeOffset, mozilla::Some(numNewSlotsOffset), preserveWrapper);
10411041
}
10421042

1043-
bool BaselineCacheIRCompiler::emitArrayJoinResult(ObjOperandId objId,
1044-
StringOperandId sepId) {
1045-
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
1046-
1047-
AutoOutputRegister output(*this);
1048-
Register obj = allocator.useRegister(masm, objId);
1049-
Register sep = allocator.useRegister(masm, sepId);
1050-
AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
1051-
1052-
allocator.discardStack(masm);
1053-
1054-
// Load obj->elements in scratch.
1055-
masm.loadPtr(Address(obj, NativeObject::offsetOfElements()), scratch);
1056-
Address lengthAddr(scratch, ObjectElements::offsetOfLength());
1057-
1058-
// If array length is 0, return empty string.
1059-
Label finished;
1060-
1061-
{
1062-
Label arrayNotEmpty;
1063-
masm.branch32(Assembler::NotEqual, lengthAddr, Imm32(0), &arrayNotEmpty);
1064-
masm.movePtr(ImmGCPtr(cx_->names().empty_), scratch);
1065-
masm.tagValue(JSVAL_TYPE_STRING, scratch, output.valueReg());
1066-
masm.jump(&finished);
1067-
masm.bind(&arrayNotEmpty);
1068-
}
1069-
1070-
Label vmCall;
1071-
1072-
// Otherwise, handle array length 1 case.
1073-
masm.branch32(Assembler::NotEqual, lengthAddr, Imm32(1), &vmCall);
1074-
1075-
// But only if initializedLength is also 1.
1076-
Address initLength(scratch, ObjectElements::offsetOfInitializedLength());
1077-
masm.branch32(Assembler::NotEqual, initLength, Imm32(1), &vmCall);
1078-
1079-
// And only if elem0 is a string.
1080-
Address elementAddr(scratch, 0);
1081-
masm.branchTestString(Assembler::NotEqual, elementAddr, &vmCall);
1082-
1083-
// Store the value.
1084-
masm.loadValue(elementAddr, output.valueReg());
1085-
masm.jump(&finished);
1086-
1087-
// Otherwise call into the VM.
1088-
{
1089-
masm.bind(&vmCall);
1090-
1091-
AutoStubFrame stubFrame(*this);
1092-
stubFrame.enter(masm, scratch);
1093-
1094-
masm.Push(sep);
1095-
masm.Push(obj);
1096-
1097-
using Fn = JSString* (*)(JSContext*, HandleObject, HandleString);
1098-
callVM<Fn, jit::ArrayJoin>(masm);
1099-
1100-
stubFrame.leave(masm);
1101-
1102-
masm.tagValue(JSVAL_TYPE_STRING, ReturnReg, output.valueReg());
1103-
}
1104-
1105-
masm.bind(&finished);
1106-
1107-
return true;
1108-
}
1109-
11101043
bool BaselineCacheIRCompiler::emitIsArrayResult(ValOperandId inputId) {
11111044
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
11121045

js/src/jit/CacheIRCompiler.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7390,6 +7390,69 @@ bool CacheIRCompiler::emitArgumentsSliceResult(uint32_t templateObjectOffset,
73907390
return true;
73917391
}
73927392

7393+
bool CacheIRCompiler::emitArrayJoinResult(ObjOperandId objId,
7394+
StringOperandId sepId) {
7395+
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
7396+
7397+
AutoCallVM callvm(masm, this, allocator);
7398+
7399+
Register obj = allocator.useRegister(masm, objId);
7400+
Register sep = allocator.useRegister(masm, sepId);
7401+
AutoScratchRegisterMaybeOutput scratch(allocator, masm, callvm.output());
7402+
7403+
// Discard the stack to ensure it's balanced when we skip the vm-call.
7404+
allocator.discardStack(masm);
7405+
7406+
// Load obj->elements in scratch.
7407+
masm.loadPtr(Address(obj, NativeObject::offsetOfElements()), scratch);
7408+
Address lengthAddr(scratch, ObjectElements::offsetOfLength());
7409+
7410+
// If array length is 0, return empty string.
7411+
Label finished;
7412+
7413+
{
7414+
Label arrayNotEmpty;
7415+
masm.branch32(Assembler::NotEqual, lengthAddr, Imm32(0), &arrayNotEmpty);
7416+
masm.movePtr(ImmGCPtr(cx_->names().empty_), scratch);
7417+
masm.tagValue(JSVAL_TYPE_STRING, scratch, callvm.outputValueReg());
7418+
masm.jump(&finished);
7419+
masm.bind(&arrayNotEmpty);
7420+
}
7421+
7422+
Label vmCall;
7423+
7424+
// Otherwise, handle array length 1 case.
7425+
masm.branch32(Assembler::NotEqual, lengthAddr, Imm32(1), &vmCall);
7426+
7427+
// But only if initializedLength is also 1.
7428+
Address initLength(scratch, ObjectElements::offsetOfInitializedLength());
7429+
masm.branch32(Assembler::NotEqual, initLength, Imm32(1), &vmCall);
7430+
7431+
// And only if elem0 is a string.
7432+
Address elementAddr(scratch, 0);
7433+
masm.branchTestString(Assembler::NotEqual, elementAddr, &vmCall);
7434+
7435+
// Store the value.
7436+
masm.loadValue(elementAddr, callvm.outputValueReg());
7437+
masm.jump(&finished);
7438+
7439+
// Otherwise call into the VM.
7440+
{
7441+
masm.bind(&vmCall);
7442+
7443+
callvm.prepare();
7444+
7445+
masm.Push(sep);
7446+
masm.Push(obj);
7447+
7448+
using Fn = JSString* (*)(JSContext*, HandleObject, HandleString);
7449+
callvm.call<Fn, jit::ArrayJoin>();
7450+
}
7451+
7452+
masm.bind(&finished);
7453+
return true;
7454+
}
7455+
73937456
bool CacheIRCompiler::emitStoreTypedArrayElement(ObjOperandId objId,
73947457
Scalar::Type elementType,
73957458
IntPtrOperandId indexId,

js/src/jit/CacheIROps.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1175,7 +1175,7 @@
11751175
rhs: ValId
11761176

11771177
- name: ArrayJoinResult
1178-
shared: false
1178+
shared: true
11791179
transpile: true
11801180
cost_estimate: 5
11811181
args:

js/src/jit/IonCacheIRCompiler.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2330,11 +2330,6 @@ bool IonCacheIRCompiler::emitLoadArgumentDynamicSlot(ValOperandId resultId,
23302330
MOZ_CRASH("Call ICs not used in ion");
23312331
}
23322332

2333-
bool IonCacheIRCompiler::emitArrayJoinResult(ObjOperandId objId,
2334-
StringOperandId sepId) {
2335-
MOZ_CRASH("Call ICs not used in ion");
2336-
}
2337-
23382333
bool IonCacheIRCompiler::emitIsArrayResult(ValOperandId inputId) {
23392334
MOZ_CRASH("Call ICs not used in ion");
23402335
}

0 commit comments

Comments
 (0)