Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions lib/JIT.php
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,8 @@ private function isSkippedCompilerHotPathName(string $name): bool
|| str_contains($lower, 'findcoalesce')
|| str_contains($lower, 'resolvecoalesce')
|| str_contains($lower, 'resolveisset')
|| str_contains($lower, 'operandschainequal');
|| str_contains($lower, 'operandschainequal')
|| str_contains($lower, 'isredundantcoalescetailassign');
}

private function isSkippedSelfHostEntryName(string $name): bool
Expand Down Expand Up @@ -416,7 +417,7 @@ private function isSkippedWebBootstrapHotPathName(string $name): bool
|| str_contains($lower, 'deployroot')
|| str_contains($lower, 'sourcebundler')
|| (str_contains($lower, '\\web\\conststringfolder::') && !$this->isConstStringFolderRealLoweringMethod($lower))
|| (str_contains($lower, '\\web\\superglobals::') && !str_ends_with($lower, '::issuperglobalname'));
|| str_contains($lower, '\\web\\superglobals::');
}


Expand All @@ -439,6 +440,11 @@ private function isSkippedLibSpineSmokeHotPathName(string $name): bool
/** IncludePathResolver methods with safe LLVM 9 lowering during self-host AOT (#816). */
private function isIncludePathResolverRealLoweringMethod(string $lower): bool
{
// resolve() nullable return still hits ICmp type mismatch in full self-host probe (#1097).
if ($this->shouldUseSelfHostJitStubs()) {
return false;
}

return str_ends_with($lower, '::resolve');
}

Expand Down
19 changes: 19 additions & 0 deletions lib/JIT/Call/Native.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,25 @@ protected function compileArg(Context $context, Variable $arg, int $argNum): Val
$value = $context->helper->loadValue($arg);
switch ($typeName) {
case '__object__*':
if (
null !== $arg->objectPropertySlot
&& Variable::TYPE_VALUE === $arg->objectPropertyType
) {
return $context->builder->call(
$context->lookupFunction('__value__readObject'),
$value
);
}
$valueTy = $value->typeOf();
if (
\PHPLLVM\Type::KIND_POINTER === $valueTy->getKind()
&& '__value__' === $context->getStringFromType($valueTy->getElementType())
) {
return $context->builder->call(
$context->lookupFunction('__value__readObject'),
$value
);
}
switch ($arg->type) {
case Variable::TYPE_OBJECT:
return $value;
Expand Down
19 changes: 19 additions & 0 deletions lib/JIT/Call/Native.pre
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,25 @@ class Native implements Call {
$value = $context->helper->loadValue($arg);
switch ($typeName) {
case '__object__*':
if (
null !== $arg->objectPropertySlot
&& Variable::TYPE_VALUE === $arg->objectPropertyType
) {
return $context->builder->call(
$context->lookupFunction('__value__readObject'),
$value
);
}
$valueTy = $value->typeOf();
if (
\PHPLLVM\Type::KIND_POINTER === $valueTy->getKind()
&& '__value__' === $context->getStringFromType($valueTy->getElementType())
) {
return $context->builder->call(
$context->lookupFunction('__value__readObject'),
$value
);
}
switch ($arg->type) {
case Variable::TYPE_OBJECT:
return $value;
Expand Down
43 changes: 34 additions & 9 deletions lib/JIT/Helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -884,12 +884,18 @@ public function binaryOp(OpCode $opcode, Variable $left, Variable $right): Varia
}
}
if (Variable::TYPE_OBJECT === $leftType && $leftType === $rightType) {
$voidp = $this->context->getTypeFromString('void')->pointerType(0);
$leftNorm = $this->context->builder->pointerCast($leftValue, $voidp);
$rightNorm = $this->context->builder->pointerCast($rightValue, $voidp);
$sizeT = $this->context->getTypeFromString('size_t');
$leftPtr = $this->context->builder->ptrToInt($leftNorm, $sizeT);
$rightPtr = $this->context->builder->ptrToInt($rightNorm, $sizeT);
if (OpCode::TYPE_IDENTICAL === $opcode->type) {
$result = $this->context->builder->icmp(Builder::INT_EQ, $leftValue, $rightValue);
$result = $this->context->builder->icmp(Builder::INT_EQ, $leftPtr, $rightPtr);
goto return_bool;
}
if (OpCode::TYPE_NOT_IDENTICAL === $opcode->type) {
$result = $this->context->builder->icmp(Builder::INT_NE, $leftValue, $rightValue);
$result = $this->context->builder->icmp(Builder::INT_NE, $leftPtr, $rightPtr);
goto return_bool;
}
}
Expand Down Expand Up @@ -978,16 +984,38 @@ public function loadValue(Variable $variable): PHPLLVM\Value {
$this->context->getTypeFromString('__hashtable__*')
);
}
if (Variable::TYPE_OBJECT === $variable->objectPropertyType) {
return $this->context->builder->pointerCast(
$loaded,
$this->context->getTypeFromString('__object__*')
);
}
if (Variable::TYPE_STRING === $variable->objectPropertyType) {
return $this->context->builder->pointerCast(
$loaded,
$this->context->getTypeFromString('__string__*')
);
}
if (Variable::TYPE_VALUE === $variable->objectPropertyType) {
$valuePtr = $this->context->builder->pointerCast(
$loaded,
$this->context->getTypeFromString('__value__*')
);
if (Variable::TYPE_OBJECT === $variable->type) {
return $this->context->builder->call(
$this->context->lookupFunction('__value__readObject'),
$valuePtr
);
}

return $valuePtr;
}

$llvmType = Variable::getStringType($variable->objectPropertyType);

return $this->context->builder->pointerCast(
$loaded,
$this->context->getTypeFromString('__value__*')
$this->context->getTypeFromString($llvmType)
);
}
if ($variable->kind === Variable::KIND_VALUE) {
Expand All @@ -1007,14 +1035,11 @@ private static function isOrderedCompareOpcode(int $opcodeType): bool
private function operandJitType(Variable $var): int
{
if (null !== $var->objectPropertySlot && null !== $var->objectPropertyType) {
if (Variable::TYPE_HASHTABLE === $var->objectPropertyType) {
return Variable::TYPE_HASHTABLE;
}
if (Variable::TYPE_STRING === $var->objectPropertyType) {
return Variable::TYPE_STRING;
if (Variable::TYPE_VALUE === $var->objectPropertyType) {
return Variable::TYPE_VALUE;
}

return Variable::TYPE_VALUE;
return $var->objectPropertyType;
}

return $var->type;
Expand Down
33 changes: 26 additions & 7 deletions lib/JIT/Helper.pre
Original file line number Diff line number Diff line change
Expand Up @@ -444,16 +444,38 @@ return_bool:
$this->context->getTypeFromString('__hashtable__*')
);
}
if (Variable::TYPE_OBJECT === $variable->objectPropertyType) {
return $this->context->builder->pointerCast(
$loaded,
$this->context->getTypeFromString('__object__*')
);
}
if (Variable::TYPE_STRING === $variable->objectPropertyType) {
return $this->context->builder->pointerCast(
$loaded,
$this->context->getTypeFromString('__string__*')
);
}
if (Variable::TYPE_VALUE === $variable->objectPropertyType) {
$valuePtr = $this->context->builder->pointerCast(
$loaded,
$this->context->getTypeFromString('__value__*')
);
if (Variable::TYPE_OBJECT === $variable->type) {
return $this->context->builder->call(
$this->context->lookupFunction('__value__readObject'),
$valuePtr
);
}

return $valuePtr;
}

$llvmType = Variable::getStringType($variable->objectPropertyType);

return $this->context->builder->pointerCast(
$loaded,
$this->context->getTypeFromString('__value__*')
$this->context->getTypeFromString($llvmType)
);
}
if ($variable->kind === Variable::KIND_VALUE) {
Expand All @@ -465,14 +487,11 @@ return_bool:
private function operandJitType(Variable $var): int
{
if (null !== $var->objectPropertySlot && null !== $var->objectPropertyType) {
if (Variable::TYPE_HASHTABLE === $var->objectPropertyType) {
return Variable::TYPE_HASHTABLE;
}
if (Variable::TYPE_STRING === $var->objectPropertyType) {
return Variable::TYPE_STRING;
if (Variable::TYPE_VALUE === $var->objectPropertyType) {
return Variable::TYPE_VALUE;
}

return Variable::TYPE_VALUE;
return $var->objectPropertyType;
}

return $var->type;
Expand Down
4 changes: 1 addition & 3 deletions lib/JIT/JitValueBox.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,7 @@ public static function isValueOperand(Variable $var): bool
return true;
}
return null !== $var->objectPropertySlot
&& null !== $var->objectPropertyType
&& Variable::TYPE_HASHTABLE !== $var->objectPropertyType
&& Variable::TYPE_STRING !== $var->objectPropertyType;
&& Variable::TYPE_VALUE === $var->objectPropertyType;
}

/**
Expand Down
Loading