X64 Crankshaft: Add Typeof and TypeofIs to x64 lithium. Fix presubmit.
Review URL: http://codereview.chromium.org/6568004 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6912 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
a0b8d5a55c
commit
65443b3879
@ -322,8 +322,7 @@ int LCodeGen::ToInteger32(LConstantOperand* op) const {
|
|||||||
|
|
||||||
Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const {
|
Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const {
|
||||||
Handle<Object> literal = chunk_->LookupLiteral(op);
|
Handle<Object> literal = chunk_->LookupLiteral(op);
|
||||||
Representation r = chunk_->LookupLiteralRepresentation(op);
|
ASSERT(chunk_->LookupLiteralRepresentation(op).IsTagged());
|
||||||
ASSERT(r.IsTagged());
|
|
||||||
return literal;
|
return literal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3175,63 +3174,42 @@ void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
|
|||||||
|
|
||||||
|
|
||||||
void LCodeGen::DoTypeof(LTypeof* instr) {
|
void LCodeGen::DoTypeof(LTypeof* instr) {
|
||||||
Abort("Unimplemented: %s", "DoTypeof");
|
LOperand* input = instr->InputAt(0);
|
||||||
|
if (input->IsConstantOperand()) {
|
||||||
|
__ Push(ToHandle(LConstantOperand::cast(input)));
|
||||||
|
} else if (input->IsRegister()) {
|
||||||
|
__ push(ToRegister(input));
|
||||||
|
} else {
|
||||||
|
ASSERT(input->IsStackSlot());
|
||||||
|
__ push(ToOperand(input));
|
||||||
|
}
|
||||||
|
CallRuntime(Runtime::kTypeof, 1, instr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LCodeGen::DoTypeofIs(LTypeofIs* instr) {
|
void LCodeGen::DoTypeofIs(LTypeofIs* instr) {
|
||||||
Abort("Unimplemented: %s", "DoTypeofIs");
|
Register input = ToRegister(instr->InputAt(0));
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LCodeGen::DoIsConstructCall(LIsConstructCall* instr) {
|
|
||||||
Register result = ToRegister(instr->result());
|
Register result = ToRegister(instr->result());
|
||||||
NearLabel true_label;
|
Label true_label;
|
||||||
NearLabel false_label;
|
Label false_label;
|
||||||
NearLabel done;
|
NearLabel done;
|
||||||
|
|
||||||
EmitIsConstructCall(result);
|
Condition final_branch_condition = EmitTypeofIs(&true_label,
|
||||||
__ j(equal, &true_label);
|
&false_label,
|
||||||
|
input,
|
||||||
|
instr->type_literal());
|
||||||
|
__ j(final_branch_condition, &true_label);
|
||||||
|
__ bind(&false_label);
|
||||||
__ LoadRoot(result, Heap::kFalseValueRootIndex);
|
__ LoadRoot(result, Heap::kFalseValueRootIndex);
|
||||||
__ jmp(&done);
|
__ jmp(&done);
|
||||||
|
|
||||||
__ bind(&true_label);
|
__ bind(&true_label);
|
||||||
__ LoadRoot(result, Heap::kTrueValueRootIndex);
|
__ LoadRoot(result, Heap::kTrueValueRootIndex);
|
||||||
|
|
||||||
|
|
||||||
__ bind(&done);
|
__ bind(&done);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
|
|
||||||
Register temp = ToRegister(instr->TempAt(0));
|
|
||||||
int true_block = chunk_->LookupDestination(instr->true_block_id());
|
|
||||||
int false_block = chunk_->LookupDestination(instr->false_block_id());
|
|
||||||
|
|
||||||
EmitIsConstructCall(temp);
|
|
||||||
EmitBranch(true_block, false_block, equal);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LCodeGen::EmitIsConstructCall(Register temp) {
|
|
||||||
// Get the frame pointer for the calling frame.
|
|
||||||
__ movq(temp, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
|
|
||||||
|
|
||||||
// Skip the arguments adaptor frame if it exists.
|
|
||||||
NearLabel check_frame_marker;
|
|
||||||
__ SmiCompare(Operand(temp, StandardFrameConstants::kContextOffset),
|
|
||||||
Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
|
|
||||||
__ j(not_equal, &check_frame_marker);
|
|
||||||
__ movq(temp, Operand(rax, StandardFrameConstants::kCallerFPOffset));
|
|
||||||
|
|
||||||
// Check the marker in the calling frame.
|
|
||||||
__ bind(&check_frame_marker);
|
|
||||||
__ SmiCompare(Operand(temp, StandardFrameConstants::kMarkerOffset),
|
|
||||||
Smi::FromInt(StackFrame::CONSTRUCT));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LCodeGen::EmitPushConstantOperand(LOperand* operand) {
|
void LCodeGen::EmitPushConstantOperand(LOperand* operand) {
|
||||||
ASSERT(operand->IsConstantOperand());
|
ASSERT(operand->IsConstantOperand());
|
||||||
LConstantOperand* const_op = LConstantOperand::cast(operand);
|
LConstantOperand* const_op = LConstantOperand::cast(operand);
|
||||||
@ -3329,6 +3307,54 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LCodeGen::DoIsConstructCall(LIsConstructCall* instr) {
|
||||||
|
Register result = ToRegister(instr->result());
|
||||||
|
NearLabel true_label;
|
||||||
|
NearLabel false_label;
|
||||||
|
NearLabel done;
|
||||||
|
|
||||||
|
EmitIsConstructCall(result);
|
||||||
|
__ j(equal, &true_label);
|
||||||
|
|
||||||
|
__ LoadRoot(result, Heap::kFalseValueRootIndex);
|
||||||
|
__ jmp(&done);
|
||||||
|
|
||||||
|
__ bind(&true_label);
|
||||||
|
__ LoadRoot(result, Heap::kTrueValueRootIndex);
|
||||||
|
|
||||||
|
|
||||||
|
__ bind(&done);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
|
||||||
|
Register temp = ToRegister(instr->TempAt(0));
|
||||||
|
int true_block = chunk_->LookupDestination(instr->true_block_id());
|
||||||
|
int false_block = chunk_->LookupDestination(instr->false_block_id());
|
||||||
|
|
||||||
|
EmitIsConstructCall(temp);
|
||||||
|
EmitBranch(true_block, false_block, equal);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LCodeGen::EmitIsConstructCall(Register temp) {
|
||||||
|
// Get the frame pointer for the calling frame.
|
||||||
|
__ movq(temp, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
|
||||||
|
|
||||||
|
// Skip the arguments adaptor frame if it exists.
|
||||||
|
NearLabel check_frame_marker;
|
||||||
|
__ SmiCompare(Operand(temp, StandardFrameConstants::kContextOffset),
|
||||||
|
Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
|
||||||
|
__ j(not_equal, &check_frame_marker);
|
||||||
|
__ movq(temp, Operand(rax, StandardFrameConstants::kCallerFPOffset));
|
||||||
|
|
||||||
|
// Check the marker in the calling frame.
|
||||||
|
__ bind(&check_frame_marker);
|
||||||
|
__ SmiCompare(Operand(temp, StandardFrameConstants::kMarkerOffset),
|
||||||
|
Smi::FromInt(StackFrame::CONSTRUCT));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
|
void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
|
||||||
// No code for lazy bailout instruction. Used to capture environment after a
|
// No code for lazy bailout instruction. Used to capture environment after a
|
||||||
// call for populating the safepoint data with deoptimization data.
|
// call for populating the safepoint data with deoptimization data.
|
||||||
|
@ -1951,14 +1951,13 @@ LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
|
|||||||
|
|
||||||
|
|
||||||
LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) {
|
LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) {
|
||||||
Abort("Unimplemented: %s", "DoTypeof");
|
LTypeof* result = new LTypeof(UseAtStart(instr->value()));
|
||||||
return NULL;
|
return MarkAsCall(DefineFixed(result, rax), instr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) {
|
LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) {
|
||||||
Abort("Unimplemented: %s", "DoTypeofIs");
|
return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value())));
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user