Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(97)

Unified Diff: src/x64/codegen-x64.cc

Issue 2084017: Version 2.2.11... (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/x64/builtins-x64.cc ('k') | src/x64/cpu-x64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/x64/codegen-x64.cc
===================================================================
--- src/x64/codegen-x64.cc (revision 4699)
+++ src/x64/codegen-x64.cc (working copy)
@@ -27,6 +27,8 @@
#include "v8.h"
+#if defined(V8_TARGET_ARCH_X64)
+
#include "bootstrapper.h"
#include "codegen-inl.h"
#include "compiler.h"
@@ -678,11 +680,51 @@
void DeferredReferenceSetKeyedValue::Generate() {
__ IncrementCounter(&Counters::keyed_store_inline_miss, 1);
- // Push receiver and key arguments on the stack.
- __ push(receiver_);
- __ push(key_);
- // Move value argument to eax as expected by the IC stub.
- if (!value_.is(rax)) __ movq(rax, value_);
+ // Move value, receiver, and key to registers rax, rdx, and rcx, as
+ // the IC stub expects.
+ // Move value to rax, using xchg if the receiver or key is in rax.
+ if (!value_.is(rax)) {
+ if (!receiver_.is(rax) && !key_.is(rax)) {
+ __ movq(rax, value_);
+ } else {
+ __ xchg(rax, value_);
+ // Update receiver_ and key_ if they are affected by the swap.
+ if (receiver_.is(rax)) {
+ receiver_ = value_;
+ } else if (receiver_.is(value_)) {
+ receiver_ = rax;
+ }
+ if (key_.is(rax)) {
+ key_ = value_;
+ } else if (key_.is(value_)) {
+ key_ = rax;
+ }
+ }
+ }
+ // Value is now in rax. Its original location is remembered in value_,
+ // and the value is restored to value_ before returning.
+ // The variables receiver_ and key_ are not preserved.
+ // Move receiver and key to rdx and rcx, swapping if necessary.
+ if (receiver_.is(rdx)) {
+ if (!key_.is(rcx)) {
+ __ movq(rcx, key_);
+ } // Else everything is already in the right place.
+ } else if (receiver_.is(rcx)) {
+ if (key_.is(rdx)) {
+ __ xchg(rcx, rdx);
+ } else if (key_.is(rcx)) {
+ __ movq(rdx, receiver_);
+ } else {
+ __ movq(rdx, receiver_);
+ __ movq(rcx, key_);
+ }
+ } else if (key_.is(rcx)) {
+ __ movq(rdx, receiver_);
+ } else {
+ __ movq(rcx, key_);
+ __ movq(rdx, receiver_);
+ }
+
// Call the IC stub.
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
@@ -695,11 +737,8 @@
// Here we use masm_-> instead of the __ macro because this is the
// instruction that gets patched and coverage code gets in the way.
masm_->testl(rax, Immediate(-delta_to_patch_site));
- // Restore value (returned from store IC), key and receiver
- // registers.
+ // Restore value (returned from store IC).
if (!value_.is(rax)) __ movq(value_, rax);
- __ pop(key_);
- __ pop(receiver_);
}
@@ -1546,7 +1585,7 @@
}
Result var = frame_->Pop();
var.ToRegister();
- __ AbortIfNotSmi(var.reg(), "Non-smi value in smi-typed stack slot.");
+ __ AbortIfNotSmi(var.reg());
}
}
@@ -2799,6 +2838,7 @@
int arg_count = args->length();
for (int i = 0; i < arg_count; i++) {
Load(args->at(i));
+ frame_->SpillTop();
}
// Prepare the stack for the call to ResolvePossiblyDirectEval.
@@ -2848,6 +2888,7 @@
int arg_count = args->length();
for (int i = 0; i < arg_count; i++) {
Load(args->at(i));
+ frame_->SpillTop();
}
// Push the name of the function on the frame.
@@ -2953,6 +2994,7 @@
int arg_count = args->length();
for (int i = 0; i < arg_count; i++) {
Load(args->at(i));
+ frame_->SpillTop();
}
// Push the name of the function onto the frame.
@@ -3399,7 +3441,11 @@
new_value.type_info());
}
- __ JumpIfNotSmi(new_value.reg(), deferred->entry_label());
+ if (new_value.is_smi()) {
+ if (FLAG_debug_code) { __ AbortIfNotSmi(new_value.reg()); }
+ } else {
+ __ JumpIfNotSmi(new_value.reg(), deferred->entry_label());
+ }
if (is_increment) {
__ SmiAddConstant(kScratchRegister,
new_value.reg(),
@@ -3833,11 +3879,13 @@
__ testb(FieldOperand(kScratchRegister, Map::kBitFieldOffset),
Immediate(1 << Map::kIsUndetectable));
destination()->false_target()->Branch(not_zero);
- __ CmpInstanceType(kScratchRegister, FIRST_JS_OBJECT_TYPE);
- destination()->false_target()->Branch(less);
- __ CmpInstanceType(kScratchRegister, LAST_JS_OBJECT_TYPE);
+ __ movzxbq(kScratchRegister,
+ FieldOperand(kScratchRegister, Map::kInstanceTypeOffset));
+ __ cmpq(kScratchRegister, Immediate(FIRST_JS_OBJECT_TYPE));
+ destination()->false_target()->Branch(below);
+ __ cmpq(kScratchRegister, Immediate(LAST_JS_OBJECT_TYPE));
obj.Unuse();
- destination()->Split(less_equal);
+ destination()->Split(below_equal);
}
@@ -3921,7 +3969,7 @@
__ bind(&exit);
result.set_type_info(TypeInfo::Smi());
if (FLAG_debug_code) {
- __ AbortIfNotSmi(result.reg(), "Computed arguments.length is not a smi.");
+ __ AbortIfNotSmi(result.reg());
}
frame_->Push(&result);
}
@@ -4329,7 +4377,7 @@
__ PrepareCallCFunction(0);
__ CallCFunction(ExternalReference::random_uint32_function(), 0);
- // Convert 32 random bits in eax to 0.(32 random bits) in a double
+ // Convert 32 random bits in rax to 0.(32 random bits) in a double
// by computing:
// ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
__ movl(rcx, Immediate(0x49800000)); // 1.0 x 2^20 as single.
@@ -5100,10 +5148,9 @@
value.ToRegister();
if (value.is_number()) {
- Comment cmnt(masm_, "ONLY_NUMBER");
// Fast case if TypeInfo indicates only numbers.
if (FLAG_debug_code) {
- __ AbortIfNotNumber(value.reg(), "ToBoolean operand is not a number.");
+ __ AbortIfNotNumber(value.reg());
}
// Smi => false iff zero.
__ SmiCompare(value.reg(), Smi::FromInt(0));
@@ -5876,7 +5923,7 @@
if (left_side.is_smi()) {
if (FLAG_debug_code) {
- __ AbortIfNotSmi(left_side.reg(), "Non-smi value inferred as smi.");
+ __ AbortIfNotSmi(left_side.reg());
}
} else {
Condition left_is_smi = masm_->CheckSmi(left_side.reg());
@@ -6748,8 +6795,7 @@
Condition is_smi = masm_->CheckSmi(operand->reg());
deferred->Branch(NegateCondition(is_smi));
} else if (FLAG_debug_code) {
- __ AbortIfNotSmi(operand->reg(),
- "Static type info claims non-smi is smi in (const SHL smi).");
+ __ AbortIfNotSmi(operand->reg());
}
__ Move(answer.reg(), smi_value);
@@ -7011,8 +7057,44 @@
left->reg(),
rcx,
overwrite_mode);
- __ JumpIfNotBothSmi(left->reg(), rcx, deferred->entry_label());
+ Label do_op;
+ if (right_type_info.IsSmi()) {
+ if (FLAG_debug_code) {
+ __ AbortIfNotSmi(right->reg());
+ }
+ __ movq(answer.reg(), left->reg());
+ // If left is not known to be a smi, check if it is.
+ // If left is not known to be a number, and it isn't a smi, check if
+ // it is a HeapNumber.
+ if (!left_type_info.IsSmi()) {
+ __ JumpIfSmi(answer.reg(), &do_op);
+ if (!left_type_info.IsNumber()) {
+ // Branch if not a heapnumber.
+ __ Cmp(FieldOperand(answer.reg(), HeapObject::kMapOffset),
+ Factory::heap_number_map());
+ deferred->Branch(not_equal);
+ }
+ // Load integer value into answer register using truncation.
+ __ cvttsd2si(answer.reg(),
+ FieldOperand(answer.reg(), HeapNumber::kValueOffset));
+ // Branch if we might have overflowed.
+ // (False negative for Smi::kMinValue)
+ __ cmpq(answer.reg(), Immediate(0x80000000));
+ deferred->Branch(equal);
+ // TODO(lrn): Inline shifts on int32 here instead of first smi-tagging.
+ __ Integer32ToSmi(answer.reg(), answer.reg());
+ } else {
+ // Fast case - both are actually smis.
+ if (FLAG_debug_code) {
+ __ AbortIfNotSmi(left->reg());
+ }
+ }
+ } else {
+ __ JumpIfNotBothSmi(left->reg(), rcx, deferred->entry_label());
+ }
+ __ bind(&do_op);
+
// Perform the operation.
switch (op) {
case Token::SAR:
@@ -7469,7 +7551,7 @@
if (!key.is_smi()) {
__ JumpIfNotSmi(key.reg(), deferred->entry_label());
} else if (FLAG_debug_code) {
- __ AbortIfNotSmi(key.reg(), "Non-smi value in smi-typed value.");
+ __ AbortIfNotSmi(key.reg());
}
// Check that the receiver is a JSArray.
@@ -7524,8 +7606,6 @@
deferred->BindExit();
- cgen_->frame()->Push(&receiver);
- cgen_->frame()->Push(&key);
cgen_->frame()->Push(&value);
} else {
Result answer = cgen_->frame()->CallKeyedStoreIC();
@@ -7536,7 +7616,7 @@
masm->nop();
cgen_->frame()->Push(&answer);
}
- cgen_->UnloadReference(this);
+ set_unloaded();
break;
}
@@ -8898,6 +8978,7 @@
int arg_count = args->length();
for (int i = 0; i < arg_count; i++) {
Load(args->at(i));
+ frame_->SpillTop();
}
// Record the position for debugging purposes.
@@ -10014,8 +10095,8 @@
if (static_operands_type_.IsSmi()) {
// Skip smi check if we know that both arguments are smis.
if (FLAG_debug_code) {
- __ AbortIfNotSmi(left, "Static type check claimed non-smi is smi.");
- __ AbortIfNotSmi(right, "Static type check claimed non-smi is smi.");
+ __ AbortIfNotSmi(left);
+ __ AbortIfNotSmi(right);
}
if (op_ == Token::BIT_OR) {
// Handle OR here, since we do extra smi-checking in the or code below.
@@ -10198,8 +10279,8 @@
// rdx: x
if (static_operands_type_.IsNumber() && FLAG_debug_code) {
// Assert at runtime that inputs are only numbers.
- __ AbortIfNotNumber(rdx, "GenericBinaryOpStub operand not a number.");
- __ AbortIfNotNumber(rax, "GenericBinaryOpStub operand not a number.");
+ __ AbortIfNotNumber(rdx);
+ __ AbortIfNotNumber(rax);
} else {
FloatingPointHelper::CheckNumberOperands(masm, &call_runtime);
}
@@ -11589,3 +11670,5 @@
#undef __
} } // namespace v8::internal
+
+#endif // V8_TARGET_ARCH_X64
« no previous file with comments | « src/x64/builtins-x64.cc ('k') | src/x64/cpu-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698