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:
mbrandy 2015-06-03 10:21:57 -07:00 committed by Commit bot
parent 353310b7c1
commit 92d5c48f74
3 changed files with 27 additions and 18 deletions

View File

@ -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, &not_date_object);
__ CompareObjectType(object, scratch0, scratch0, JS_DATE_TYPE);
__ beq(&done);
__ bind(&not_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, &not_date_object);
__ CompareObjectType(object, scratch1, scratch1, JS_DATE_TYPE);
__ bne(&not_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(&not_date_object);
__ CallRuntime(Runtime::kThrowNotDateError, 0);
__ bind(&done);
context()->Plug(r3);
context()->Plug(result);
}

View File

@ -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));

View File

@ -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);
}