Commit c8b7c249 authored by cdai2's avatar cdai2

X87: [date] Refactor the %_DateField intrinsic to be optimizable.

port e4782a9b (r28782)

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).

BUG=
R=weiliang.lin@intel.com

Review URL: https://codereview.chromium.org/1174913002

Cr-Commit-Position: refs/heads/master@{#28948}
parent b263ac33
......@@ -3776,6 +3776,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 = eax;
Register result = eax;
Register scratch = ecx;
__ JumpIfSmi(object, &not_date_object, Label::kNear);
__ CmpObjectType(object, JS_DATE_TYPE, scratch);
__ j(equal, &done, Label::kNear);
__ 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);
......@@ -3784,19 +3806,14 @@ void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
VisitForAccumulatorValue(args->at(0)); // Load the object.
Label runtime, done, not_date_object;
Register object = eax;
Register result = eax;
Register scratch = ecx;
__ JumpIfSmi(object, &not_date_object);
__ CmpObjectType(object, JS_DATE_TYPE, scratch);
__ j(not_equal, &not_date_object);
if (index->value() == 0) {
__ mov(result, FieldOperand(object, JSDate::kValueOffset));
__ jmp(&done);
} else {
Label runtime, done;
if (index->value() < JSDate::kFirstUncachedField) {
ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
__ mov(scratch, Operand::StaticVariable(stamp));
......@@ -3804,19 +3821,16 @@ void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
__ j(not_equal, &runtime, Label::kNear);
__ mov(result, FieldOperand(object, JSDate::kValueOffset +
kPointerSize * index->value()));
__ jmp(&done);
__ jmp(&done, Label::kNear);
}
__ bind(&runtime);
__ PrepareCallCFunction(2, scratch);
__ mov(Operand(esp, 0), object);
__ mov(Operand(esp, 1 * kPointerSize), Immediate(index));
__ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
__ jmp(&done);
__ bind(&done);
}
__ bind(&not_date_object);
__ CallRuntime(Runtime::kThrowNotDateError, 0);
__ bind(&done);
context()->Plug(result);
}
......
......@@ -2019,18 +2019,13 @@ 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(eax));
__ test(object, Immediate(kSmiTagMask));
DeoptimizeIf(zero, instr, Deoptimizer::kSmi);
__ CmpObjectType(object, JS_DATE_TYPE, scratch);
DeoptimizeIf(not_equal, instr, Deoptimizer::kNotADateObject);
if (index->value() == 0) {
__ mov(result, FieldOperand(object, JSDate::kValueOffset));
} else {
Label runtime, done;
if (index->value() < JSDate::kFirstUncachedField) {
ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
__ mov(scratch, Operand::StaticVariable(stamp));
......
......@@ -1821,7 +1821,7 @@ LInstruction* LChunkBuilder::DoDateField(HDateField* instr) {
LOperand* date = UseFixed(instr->value(), eax);
LDateField* result =
new(zone()) LDateField(date, FixedTemp(ecx), instr->index());
return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY);
return MarkAsCall(DefineFixed(result, eax), instr, CANNOT_DEOPTIMIZE_EAGERLY);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment