PPC: [date] Refactor the %_DateField intrinsic to be optimizable.
Port e4782a9b46
Original commit message:
Previously the %_DateField intrinsic would also check the object and
throw an exception if you happen to pass something that is not a valid
JSDate, which (a) violates our policy for instrinsics and (b) is hard to
optimize in TurboFan (even Crankshaft has a hard time, but there we will
never inline the relevant builtins, so it doesn't show up). The throwing
part is now a separate intrinsics %_ThrowIfNotADate that throws an
exception in full codegen and deoptimizes in Crankshaft, which means the
code for the current use cases is roughly the same (modulo some register
renamings/gap moves).
R=bmeurer@chromium.org, dstence@us.ibm.com, michael_dawson@ca.ibm.com
BUG=
Review URL: https://codereview.chromium.org/1170463002
Cr-Commit-Position: refs/heads/master@{#28794}
This commit is contained in:
parent
353310b7c1
commit
92d5c48f74
@ -3915,6 +3915,28 @@ void FullCodeGenerator::EmitValueOf(CallRuntime* expr) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitThrowIfNotADate(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK_EQ(1, args->length());
|
||||
|
||||
VisitForAccumulatorValue(args->at(0)); // Load the object.
|
||||
|
||||
Label done, not_date_object;
|
||||
Register object = r3;
|
||||
Register result = r3;
|
||||
Register scratch0 = r4;
|
||||
|
||||
__ JumpIfSmi(object, ¬_date_object);
|
||||
__ CompareObjectType(object, scratch0, scratch0, JS_DATE_TYPE);
|
||||
__ beq(&done);
|
||||
__ bind(¬_date_object);
|
||||
__ CallRuntime(Runtime::kThrowNotDateError, 0);
|
||||
|
||||
__ bind(&done);
|
||||
context()->Plug(result);
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK(args->length() == 2);
|
||||
@ -3923,20 +3945,15 @@ void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
|
||||
|
||||
VisitForAccumulatorValue(args->at(0)); // Load the object.
|
||||
|
||||
Label runtime, done, not_date_object;
|
||||
Register object = r3;
|
||||
Register result = r3;
|
||||
Register scratch0 = r11;
|
||||
Register scratch1 = r4;
|
||||
|
||||
__ JumpIfSmi(object, ¬_date_object);
|
||||
__ CompareObjectType(object, scratch1, scratch1, JS_DATE_TYPE);
|
||||
__ bne(¬_date_object);
|
||||
|
||||
if (index->value() == 0) {
|
||||
__ LoadP(result, FieldMemOperand(object, JSDate::kValueOffset));
|
||||
__ b(&done);
|
||||
} else {
|
||||
Label runtime, done;
|
||||
if (index->value() < JSDate::kFirstUncachedField) {
|
||||
ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
|
||||
__ mov(scratch1, Operand(stamp));
|
||||
@ -3954,13 +3971,10 @@ void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
|
||||
__ PrepareCallCFunction(2, scratch1);
|
||||
__ LoadSmiLiteral(r4, index);
|
||||
__ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
|
||||
__ b(&done);
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
__ bind(¬_date_object);
|
||||
__ CallRuntime(Runtime::kThrowNotDateError, 0);
|
||||
__ bind(&done);
|
||||
context()->Plug(r3);
|
||||
context()->Plug(result);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1923,20 +1923,15 @@ void LCodeGen::DoDateField(LDateField* instr) {
|
||||
Register result = ToRegister(instr->result());
|
||||
Register scratch = ToRegister(instr->temp());
|
||||
Smi* index = instr->index();
|
||||
Label runtime, done;
|
||||
DCHECK(object.is(result));
|
||||
DCHECK(object.is(r3));
|
||||
DCHECK(!scratch.is(scratch0()));
|
||||
DCHECK(!scratch.is(object));
|
||||
|
||||
__ TestIfSmi(object, r0);
|
||||
DeoptimizeIf(eq, instr, Deoptimizer::kSmi, cr0);
|
||||
__ CompareObjectType(object, scratch, scratch, JS_DATE_TYPE);
|
||||
DeoptimizeIf(ne, instr, Deoptimizer::kNotADateObject);
|
||||
|
||||
if (index->value() == 0) {
|
||||
__ LoadP(result, FieldMemOperand(object, JSDate::kValueOffset));
|
||||
} else {
|
||||
Label runtime, done;
|
||||
if (index->value() < JSDate::kFirstUncachedField) {
|
||||
ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
|
||||
__ mov(scratch, Operand(stamp));
|
||||
|
@ -1815,7 +1815,7 @@ LInstruction* LChunkBuilder::DoDateField(HDateField* instr) {
|
||||
LOperand* object = UseFixed(instr->value(), r3);
|
||||
LDateField* result =
|
||||
new (zone()) LDateField(object, FixedTemp(r4), instr->index());
|
||||
return MarkAsCall(DefineFixed(result, r3), instr, CAN_DEOPTIMIZE_EAGERLY);
|
||||
return MarkAsCall(DefineFixed(result, r3), instr, CANNOT_DEOPTIMIZE_EAGERLY);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user