MIPS: Port Math.pow inlining to ARM.
Port r10210 (6b15398) and r10226 (cdc75a453). BUG= TEST= Review URL: http://codereview.chromium.org/8896021 Patch from Daniel Kalmar <kalmard@homejinni.com>. git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10234 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
42a85ce584
commit
6fdf50c040
@ -3592,113 +3592,218 @@ void StackCheckStub::Generate(MacroAssembler* masm) {
|
|||||||
|
|
||||||
|
|
||||||
void MathPowStub::Generate(MacroAssembler* masm) {
|
void MathPowStub::Generate(MacroAssembler* masm) {
|
||||||
Label call_runtime;
|
CpuFeatures::Scope fpu_scope(FPU);
|
||||||
|
const Register base = a1;
|
||||||
|
const Register exponent = a2;
|
||||||
|
const Register heapnumbermap = t1;
|
||||||
|
const Register heapnumber = v0;
|
||||||
|
const DoubleRegister double_base = f2;
|
||||||
|
const DoubleRegister double_exponent = f4;
|
||||||
|
const DoubleRegister double_result = f0;
|
||||||
|
const DoubleRegister double_scratch = f6;
|
||||||
|
const FPURegister single_scratch = f8;
|
||||||
|
const Register scratch = t5;
|
||||||
|
const Register scratch2 = t3;
|
||||||
|
|
||||||
if (CpuFeatures::IsSupported(FPU)) {
|
Label call_runtime, done, exponent_not_smi, int_exponent;
|
||||||
CpuFeatures::Scope scope(FPU);
|
if (exponent_type_ == ON_STACK) {
|
||||||
|
Label base_is_smi, unpack_exponent;
|
||||||
Label base_not_smi;
|
// The exponent and base are supplied as arguments on the stack.
|
||||||
Label exponent_not_smi;
|
// This can only happen if the stub is called from non-optimized code.
|
||||||
Label convert_exponent;
|
// Load input parameters from stack to double registers.
|
||||||
|
|
||||||
const Register base = a0;
|
|
||||||
const Register exponent = a2;
|
|
||||||
const Register heapnumbermap = t1;
|
|
||||||
const Register heapnumber = s0; // Callee-saved register.
|
|
||||||
const Register scratch = t2;
|
|
||||||
const Register scratch2 = t3;
|
|
||||||
|
|
||||||
// Alocate FP values in the ABI-parameter-passing regs.
|
|
||||||
const DoubleRegister double_base = f12;
|
|
||||||
const DoubleRegister double_exponent = f14;
|
|
||||||
const DoubleRegister double_result = f0;
|
|
||||||
const DoubleRegister double_scratch = f2;
|
|
||||||
|
|
||||||
__ LoadRoot(heapnumbermap, Heap::kHeapNumberMapRootIndex);
|
|
||||||
__ lw(base, MemOperand(sp, 1 * kPointerSize));
|
__ lw(base, MemOperand(sp, 1 * kPointerSize));
|
||||||
__ lw(exponent, MemOperand(sp, 0 * kPointerSize));
|
__ lw(exponent, MemOperand(sp, 0 * kPointerSize));
|
||||||
|
|
||||||
// Convert base to double value and store it in f0.
|
__ LoadRoot(heapnumbermap, Heap::kHeapNumberMapRootIndex);
|
||||||
__ JumpIfNotSmi(base, &base_not_smi);
|
|
||||||
// Base is a Smi. Untag and convert it.
|
|
||||||
__ SmiUntag(base);
|
|
||||||
__ mtc1(base, double_scratch);
|
|
||||||
__ cvt_d_w(double_base, double_scratch);
|
|
||||||
__ Branch(&convert_exponent);
|
|
||||||
|
|
||||||
__ bind(&base_not_smi);
|
__ JumpIfSmi(base, &base_is_smi);
|
||||||
__ lw(scratch, FieldMemOperand(base, JSObject::kMapOffset));
|
__ lw(scratch, FieldMemOperand(base, JSObject::kMapOffset));
|
||||||
__ Branch(&call_runtime, ne, scratch, Operand(heapnumbermap));
|
__ Branch(&call_runtime, ne, scratch, Operand(heapnumbermap));
|
||||||
// Base is a heapnumber. Load it into double register.
|
|
||||||
__ ldc1(double_base, FieldMemOperand(base, HeapNumber::kValueOffset));
|
|
||||||
|
|
||||||
__ bind(&convert_exponent);
|
__ ldc1(double_base, FieldMemOperand(base, HeapNumber::kValueOffset));
|
||||||
|
__ jmp(&unpack_exponent);
|
||||||
|
|
||||||
|
__ bind(&base_is_smi);
|
||||||
|
__ SmiUntag(base);
|
||||||
|
__ mtc1(base, single_scratch);
|
||||||
|
__ cvt_d_w(double_base, single_scratch);
|
||||||
|
__ bind(&unpack_exponent);
|
||||||
|
|
||||||
__ JumpIfNotSmi(exponent, &exponent_not_smi);
|
__ JumpIfNotSmi(exponent, &exponent_not_smi);
|
||||||
__ SmiUntag(exponent);
|
__ SmiUntag(exponent);
|
||||||
|
__ jmp(&int_exponent);
|
||||||
// The base is in a double register and the exponent is
|
|
||||||
// an untagged smi. Allocate a heap number and call a
|
|
||||||
// C function for integer exponents. The register containing
|
|
||||||
// the heap number is callee-saved.
|
|
||||||
__ AllocateHeapNumber(heapnumber,
|
|
||||||
scratch,
|
|
||||||
scratch2,
|
|
||||||
heapnumbermap,
|
|
||||||
&call_runtime);
|
|
||||||
__ push(ra);
|
|
||||||
__ PrepareCallCFunction(1, 1, scratch);
|
|
||||||
__ SetCallCDoubleArguments(double_base, exponent);
|
|
||||||
{
|
|
||||||
AllowExternalCallThatCantCauseGC scope(masm);
|
|
||||||
__ CallCFunction(
|
|
||||||
ExternalReference::power_double_int_function(masm->isolate()), 1, 1);
|
|
||||||
__ pop(ra);
|
|
||||||
__ GetCFunctionDoubleResult(double_result);
|
|
||||||
}
|
|
||||||
__ sdc1(double_result,
|
|
||||||
FieldMemOperand(heapnumber, HeapNumber::kValueOffset));
|
|
||||||
__ mov(v0, heapnumber);
|
|
||||||
__ DropAndRet(2 * kPointerSize);
|
|
||||||
|
|
||||||
__ bind(&exponent_not_smi);
|
__ bind(&exponent_not_smi);
|
||||||
__ lw(scratch, FieldMemOperand(exponent, JSObject::kMapOffset));
|
__ lw(scratch, FieldMemOperand(exponent, JSObject::kMapOffset));
|
||||||
__ Branch(&call_runtime, ne, scratch, Operand(heapnumbermap));
|
__ Branch(&call_runtime, ne, scratch, Operand(heapnumbermap));
|
||||||
// Exponent is a heapnumber. Load it into double register.
|
|
||||||
__ ldc1(double_exponent,
|
__ ldc1(double_exponent,
|
||||||
FieldMemOperand(exponent, HeapNumber::kValueOffset));
|
FieldMemOperand(exponent, HeapNumber::kValueOffset));
|
||||||
|
} else if (exponent_type_ == TAGGED) {
|
||||||
|
// Base is already in double_base.
|
||||||
|
__ JumpIfNotSmi(exponent, &exponent_not_smi);
|
||||||
|
__ SmiUntag(exponent);
|
||||||
|
__ jmp(&int_exponent);
|
||||||
|
|
||||||
// The base and the exponent are in double registers.
|
__ bind(&exponent_not_smi);
|
||||||
// Allocate a heap number and call a C function for
|
__ ldc1(double_exponent,
|
||||||
// double exponents. The register containing
|
FieldMemOperand(exponent, HeapNumber::kValueOffset));
|
||||||
// the heap number is callee-saved.
|
|
||||||
__ AllocateHeapNumber(heapnumber,
|
|
||||||
scratch,
|
|
||||||
scratch2,
|
|
||||||
heapnumbermap,
|
|
||||||
&call_runtime);
|
|
||||||
__ push(ra);
|
|
||||||
__ PrepareCallCFunction(0, 2, scratch);
|
|
||||||
// ABI (o32) for func(double a, double b): a in f12, b in f14.
|
|
||||||
ASSERT(double_base.is(f12));
|
|
||||||
ASSERT(double_exponent.is(f14));
|
|
||||||
__ SetCallCDoubleArguments(double_base, double_exponent);
|
|
||||||
{
|
|
||||||
AllowExternalCallThatCantCauseGC scope(masm);
|
|
||||||
__ CallCFunction(
|
|
||||||
ExternalReference::power_double_double_function(masm->isolate()),
|
|
||||||
0,
|
|
||||||
2);
|
|
||||||
__ pop(ra);
|
|
||||||
__ GetCFunctionDoubleResult(double_result);
|
|
||||||
}
|
|
||||||
__ sdc1(double_result,
|
|
||||||
FieldMemOperand(heapnumber, HeapNumber::kValueOffset));
|
|
||||||
__ mov(v0, heapnumber);
|
|
||||||
__ DropAndRet(2 * kPointerSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
__ bind(&call_runtime);
|
if (exponent_type_ != INTEGER) {
|
||||||
__ TailCallRuntime(Runtime::kMath_pow_cfunction, 2, 1);
|
Label int_exponent_convert;
|
||||||
|
// Detect integer exponents stored as double.
|
||||||
|
__ EmitFPUTruncate(kRoundToMinusInf,
|
||||||
|
single_scratch,
|
||||||
|
double_exponent,
|
||||||
|
scratch,
|
||||||
|
scratch2,
|
||||||
|
kCheckForInexactConversion);
|
||||||
|
// scratch2 == 0 means there was no conversion error.
|
||||||
|
__ Branch(&int_exponent_convert, eq, scratch2, Operand(zero_reg));
|
||||||
|
|
||||||
|
if (exponent_type_ == ON_STACK) {
|
||||||
|
// Detect square root case. Crankshaft detects constant +/-0.5 at
|
||||||
|
// compile time and uses DoMathPowHalf instead. We then skip this check
|
||||||
|
// for non-constant cases of +/-0.5 as these hardly occur.
|
||||||
|
Label not_plus_half;
|
||||||
|
|
||||||
|
// Test for 0.5.
|
||||||
|
__ Move(double_scratch, 0.5);
|
||||||
|
__ BranchF(USE_DELAY_SLOT,
|
||||||
|
¬_plus_half,
|
||||||
|
NULL,
|
||||||
|
ne,
|
||||||
|
double_exponent,
|
||||||
|
double_scratch);
|
||||||
|
|
||||||
|
// Calculates square root of base. Check for the special case of
|
||||||
|
// Math.pow(-Infinity, 0.5) == Infinity (ECMA spec, 15.8.2.13).
|
||||||
|
__ Move(double_scratch, -V8_INFINITY);
|
||||||
|
__ BranchF(USE_DELAY_SLOT, &done, NULL, eq, double_base, double_scratch);
|
||||||
|
__ neg_d(double_result, double_scratch);
|
||||||
|
|
||||||
|
// Add +0 to convert -0 to +0.
|
||||||
|
__ add_d(double_scratch, double_base, kDoubleRegZero);
|
||||||
|
__ sqrt_d(double_result, double_scratch);
|
||||||
|
__ jmp(&done);
|
||||||
|
|
||||||
|
__ bind(¬_plus_half);
|
||||||
|
__ Move(double_scratch, -0.5);
|
||||||
|
__ BranchF(USE_DELAY_SLOT,
|
||||||
|
&call_runtime,
|
||||||
|
NULL,
|
||||||
|
ne,
|
||||||
|
double_exponent,
|
||||||
|
double_scratch);
|
||||||
|
|
||||||
|
// Calculates square root of base. Check for the special case of
|
||||||
|
// Math.pow(-Infinity, -0.5) == 0 (ECMA spec, 15.8.2.13).
|
||||||
|
__ Move(double_scratch, -V8_INFINITY);
|
||||||
|
__ BranchF(USE_DELAY_SLOT, &done, NULL, eq, double_base, double_scratch);
|
||||||
|
__ Move(double_result, kDoubleRegZero);
|
||||||
|
|
||||||
|
// Add +0 to convert -0 to +0.
|
||||||
|
__ add_d(double_scratch, double_base, kDoubleRegZero);
|
||||||
|
__ Move(double_result, 1);
|
||||||
|
__ sqrt_d(double_scratch, double_scratch);
|
||||||
|
__ div_d(double_result, double_result, double_scratch);
|
||||||
|
__ jmp(&done);
|
||||||
|
}
|
||||||
|
|
||||||
|
__ push(ra);
|
||||||
|
{
|
||||||
|
AllowExternalCallThatCantCauseGC scope(masm);
|
||||||
|
__ PrepareCallCFunction(0, 2, scratch);
|
||||||
|
__ SetCallCDoubleArguments(double_base, double_exponent);
|
||||||
|
__ CallCFunction(
|
||||||
|
ExternalReference::power_double_double_function(masm->isolate()),
|
||||||
|
0, 2);
|
||||||
|
}
|
||||||
|
__ pop(ra);
|
||||||
|
__ GetCFunctionDoubleResult(double_result);
|
||||||
|
__ jmp(&done);
|
||||||
|
|
||||||
|
__ bind(&int_exponent_convert);
|
||||||
|
__ mfc1(exponent, single_scratch);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate power with integer exponent.
|
||||||
|
__ bind(&int_exponent);
|
||||||
|
|
||||||
|
__ mov(scratch, exponent); // Back up exponent.
|
||||||
|
__ mov_d(double_scratch, double_base); // Back up base.
|
||||||
|
__ Move(double_result, 1.0);
|
||||||
|
|
||||||
|
// Get absolute value of exponent.
|
||||||
|
Label positive_exponent;
|
||||||
|
__ Branch(&positive_exponent, ge, scratch, Operand(zero_reg));
|
||||||
|
__ Subu(scratch, zero_reg, scratch);
|
||||||
|
__ bind(&positive_exponent);
|
||||||
|
|
||||||
|
Label while_true, no_carry, loop_end;
|
||||||
|
__ bind(&while_true);
|
||||||
|
|
||||||
|
__ And(scratch2, scratch, 1);
|
||||||
|
|
||||||
|
__ Branch(&no_carry, eq, scratch2, Operand(zero_reg));
|
||||||
|
__ mul_d(double_result, double_result, double_scratch);
|
||||||
|
__ bind(&no_carry);
|
||||||
|
|
||||||
|
__ sra(scratch, scratch, 1);
|
||||||
|
|
||||||
|
__ Branch(&loop_end, eq, scratch, Operand(zero_reg));
|
||||||
|
__ mul_d(double_scratch, double_scratch, double_scratch);
|
||||||
|
|
||||||
|
__ Branch(&while_true);
|
||||||
|
|
||||||
|
__ bind(&loop_end);
|
||||||
|
|
||||||
|
__ Branch(&done, ge, exponent, Operand(zero_reg));
|
||||||
|
__ Move(double_scratch, 1.0);
|
||||||
|
__ div_d(double_result, double_scratch, double_result);
|
||||||
|
// Test whether result is zero. Bail out to check for subnormal result.
|
||||||
|
// Due to subnormals, x^-y == (1/x)^y does not hold in all cases.
|
||||||
|
__ BranchF(&done, NULL, ne, double_result, kDoubleRegZero);
|
||||||
|
|
||||||
|
// double_exponent may not contain the exponent value if the input was a
|
||||||
|
// smi. We set it with exponent value before bailing out.
|
||||||
|
__ mtc1(exponent, single_scratch);
|
||||||
|
__ cvt_d_w(double_exponent, single_scratch);
|
||||||
|
|
||||||
|
// Returning or bailing out.
|
||||||
|
Counters* counters = masm->isolate()->counters();
|
||||||
|
if (exponent_type_ == ON_STACK) {
|
||||||
|
// The arguments are still on the stack.
|
||||||
|
__ bind(&call_runtime);
|
||||||
|
__ TailCallRuntime(Runtime::kMath_pow_cfunction, 2, 1);
|
||||||
|
|
||||||
|
// The stub is called from non-optimized code, which expects the result
|
||||||
|
// as heap number in exponent.
|
||||||
|
__ bind(&done);
|
||||||
|
__ AllocateHeapNumber(
|
||||||
|
heapnumber, scratch, scratch2, heapnumbermap, &call_runtime);
|
||||||
|
__ sdc1(double_result,
|
||||||
|
FieldMemOperand(heapnumber, HeapNumber::kValueOffset));
|
||||||
|
ASSERT(heapnumber.is(v0));
|
||||||
|
__ IncrementCounter(counters->math_pow(), 1, scratch, scratch2);
|
||||||
|
__ DropAndRet(2);
|
||||||
|
} else {
|
||||||
|
__ push(ra);
|
||||||
|
{
|
||||||
|
AllowExternalCallThatCantCauseGC scope(masm);
|
||||||
|
__ PrepareCallCFunction(0, 2, scratch);
|
||||||
|
__ SetCallCDoubleArguments(double_base, double_exponent);
|
||||||
|
__ CallCFunction(
|
||||||
|
ExternalReference::power_double_double_function(masm->isolate()),
|
||||||
|
0, 2);
|
||||||
|
}
|
||||||
|
__ pop(ra);
|
||||||
|
__ GetCFunctionDoubleResult(double_result);
|
||||||
|
|
||||||
|
__ bind(&done);
|
||||||
|
__ IncrementCounter(counters->math_pow(), 1, scratch, scratch2);
|
||||||
|
__ Ret();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2958,8 +2958,12 @@ void FullCodeGenerator::EmitMathPow(CallRuntime* expr) {
|
|||||||
ASSERT(args->length() == 2);
|
ASSERT(args->length() == 2);
|
||||||
VisitForStackValue(args->at(0));
|
VisitForStackValue(args->at(0));
|
||||||
VisitForStackValue(args->at(1));
|
VisitForStackValue(args->at(1));
|
||||||
MathPowStub stub(MathPowStub::ON_STACK);
|
if (CpuFeatures::IsSupported(FPU)) {
|
||||||
__ CallStub(&stub);
|
MathPowStub stub(MathPowStub::ON_STACK);
|
||||||
|
__ CallStub(&stub);
|
||||||
|
} else {
|
||||||
|
__ CallRuntime(Runtime::kMath_pow, 2);
|
||||||
|
}
|
||||||
context()->Plug(v0);
|
context()->Plug(v0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3024,58 +3024,32 @@ void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
|
|||||||
|
|
||||||
|
|
||||||
void LCodeGen::DoPower(LPower* instr) {
|
void LCodeGen::DoPower(LPower* instr) {
|
||||||
LOperand* left = instr->InputAt(0);
|
|
||||||
LOperand* right = instr->InputAt(1);
|
|
||||||
Register scratch = scratch0();
|
|
||||||
DoubleRegister result_reg = ToDoubleRegister(instr->result());
|
|
||||||
Representation exponent_type = instr->hydrogen()->right()->representation();
|
Representation exponent_type = instr->hydrogen()->right()->representation();
|
||||||
if (exponent_type.IsDouble()) {
|
// Having marked this as a call, we can use any registers.
|
||||||
// Prepare arguments and call C function.
|
// Just make sure that the input/output registers are the expected ones.
|
||||||
__ PrepareCallCFunction(0, 2, scratch);
|
ASSERT(!instr->InputAt(1)->IsDoubleRegister() ||
|
||||||
__ SetCallCDoubleArguments(ToDoubleRegister(left),
|
ToDoubleRegister(instr->InputAt(1)).is(f4));
|
||||||
ToDoubleRegister(right));
|
ASSERT(!instr->InputAt(1)->IsRegister() ||
|
||||||
__ CallCFunction(
|
ToRegister(instr->InputAt(1)).is(a2));
|
||||||
ExternalReference::power_double_double_function(isolate()), 0, 2);
|
ASSERT(ToDoubleRegister(instr->InputAt(0)).is(f2));
|
||||||
|
ASSERT(ToDoubleRegister(instr->result()).is(f0));
|
||||||
|
|
||||||
|
if (exponent_type.IsTagged()) {
|
||||||
|
Label no_deopt;
|
||||||
|
__ JumpIfSmi(a2, &no_deopt);
|
||||||
|
__ lw(t3, FieldMemOperand(a2, HeapObject::kMapOffset));
|
||||||
|
DeoptimizeIf(ne, instr->environment(), t3, Operand(at));
|
||||||
|
__ bind(&no_deopt);
|
||||||
|
MathPowStub stub(MathPowStub::TAGGED);
|
||||||
|
__ CallStub(&stub);
|
||||||
} else if (exponent_type.IsInteger32()) {
|
} else if (exponent_type.IsInteger32()) {
|
||||||
ASSERT(ToRegister(right).is(a0));
|
MathPowStub stub(MathPowStub::INTEGER);
|
||||||
// Prepare arguments and call C function.
|
__ CallStub(&stub);
|
||||||
__ PrepareCallCFunction(1, 1, scratch);
|
|
||||||
__ SetCallCDoubleArguments(ToDoubleRegister(left), ToRegister(right));
|
|
||||||
__ CallCFunction(
|
|
||||||
ExternalReference::power_double_int_function(isolate()), 1, 1);
|
|
||||||
} else {
|
} else {
|
||||||
ASSERT(exponent_type.IsTagged());
|
ASSERT(exponent_type.IsDouble());
|
||||||
ASSERT(instr->hydrogen()->left()->representation().IsDouble());
|
MathPowStub stub(MathPowStub::DOUBLE);
|
||||||
|
__ CallStub(&stub);
|
||||||
Register right_reg = ToRegister(right);
|
|
||||||
|
|
||||||
// Check for smi on the right hand side.
|
|
||||||
Label non_smi, call;
|
|
||||||
__ JumpIfNotSmi(right_reg, &non_smi);
|
|
||||||
|
|
||||||
// Untag smi and convert it to a double.
|
|
||||||
__ SmiUntag(right_reg);
|
|
||||||
FPURegister single_scratch = double_scratch0();
|
|
||||||
__ mtc1(right_reg, single_scratch);
|
|
||||||
__ cvt_d_w(result_reg, single_scratch);
|
|
||||||
__ Branch(&call);
|
|
||||||
|
|
||||||
// Heap number map check.
|
|
||||||
__ bind(&non_smi);
|
|
||||||
__ lw(scratch, FieldMemOperand(right_reg, HeapObject::kMapOffset));
|
|
||||||
__ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
|
|
||||||
DeoptimizeIf(ne, instr->environment(), scratch, Operand(at));
|
|
||||||
__ ldc1(result_reg, FieldMemOperand(right_reg, HeapNumber::kValueOffset));
|
|
||||||
|
|
||||||
// Prepare arguments and call C function.
|
|
||||||
__ bind(&call);
|
|
||||||
__ PrepareCallCFunction(0, 2, scratch);
|
|
||||||
__ SetCallCDoubleArguments(ToDoubleRegister(left), result_reg);
|
|
||||||
__ CallCFunction(
|
|
||||||
ExternalReference::power_double_double_function(isolate()), 0, 2);
|
|
||||||
}
|
}
|
||||||
// Store the result in the result register.
|
|
||||||
__ GetCFunctionDoubleResult(result_reg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1406,9 +1406,9 @@ LInstruction* LChunkBuilder::DoPower(HPower* instr) {
|
|||||||
LOperand* left = UseFixedDouble(instr->left(), f2);
|
LOperand* left = UseFixedDouble(instr->left(), f2);
|
||||||
LOperand* right = exponent_type.IsDouble() ?
|
LOperand* right = exponent_type.IsDouble() ?
|
||||||
UseFixedDouble(instr->right(), f4) :
|
UseFixedDouble(instr->right(), f4) :
|
||||||
UseFixed(instr->right(), a0);
|
UseFixed(instr->right(), a2);
|
||||||
LPower* result = new LPower(left, right);
|
LPower* result = new LPower(left, right);
|
||||||
return MarkAsCall(DefineFixedDouble(result, f6),
|
return MarkAsCall(DefineFixedDouble(result, f0),
|
||||||
instr,
|
instr,
|
||||||
CAN_DEOPTIMIZE_EAGERLY);
|
CAN_DEOPTIMIZE_EAGERLY);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user