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

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

Issue 6697023: Merge 6800:7180 from the bleeding edge branch to the experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 9 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/codegen-x64.h ('k') | src/x64/codegen-x64-inl.h » ('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 7180)
+++ src/x64/codegen-x64.cc (working copy)
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -615,11 +615,13 @@
ArgumentsAllocationMode CodeGenerator::ArgumentsMode() {
if (scope()->arguments() == NULL) return NO_ARGUMENTS_ALLOCATION;
- ASSERT(scope()->arguments_shadow() != NULL);
+
+ // In strict mode there is no need for shadow arguments.
+ ASSERT(scope()->arguments_shadow() != NULL || scope()->is_strict_mode());
// We don't want to do lazy arguments allocation for functions that
// have heap-allocated contexts, because it interfers with the
// uninitialized const tracking in the context objects.
- return (scope()->num_heap_slots() > 0)
+ return (scope()->num_heap_slots() > 0 || scope()->is_strict_mode())
? EAGER_ARGUMENTS_ALLOCATION
: LAZY_ARGUMENTS_ALLOCATION;
}
@@ -647,7 +649,9 @@
Variable* arguments = scope()->arguments();
Variable* shadow = scope()->arguments_shadow();
ASSERT(arguments != NULL && arguments->AsSlot() != NULL);
- ASSERT(shadow != NULL && shadow->AsSlot() != NULL);
+ ASSERT((shadow != NULL && shadow->AsSlot() != NULL) ||
+ scope()->is_strict_mode());
+
JumpTarget done;
bool skip_arguments = false;
if (mode == LAZY_ARGUMENTS_ALLOCATION && !initial) {
@@ -670,7 +674,9 @@
StoreToSlot(arguments->AsSlot(), NOT_CONST_INIT);
if (mode == LAZY_ARGUMENTS_ALLOCATION) done.Bind();
}
- StoreToSlot(shadow->AsSlot(), NOT_CONST_INIT);
+ if (shadow != NULL) {
+ StoreToSlot(shadow->AsSlot(), NOT_CONST_INIT);
+ }
return frame_->Pop();
}
@@ -764,7 +770,7 @@
__ AbortIfNotNumber(value.reg());
}
// Smi => false iff zero.
- __ SmiCompare(value.reg(), Smi::FromInt(0));
+ __ Cmp(value.reg(), Smi::FromInt(0));
if (value.is_smi()) {
value.Unuse();
dest->Split(not_zero);
@@ -792,7 +798,7 @@
dest->false_target()->Branch(equal);
// Smi => false iff zero.
- __ SmiCompare(value.reg(), Smi::FromInt(0));
+ __ Cmp(value.reg(), Smi::FromInt(0));
dest->false_target()->Branch(equal);
Condition is_smi = masm_->CheckSmi(value.reg());
dest->true_target()->Branch(is_smi);
@@ -1034,7 +1040,7 @@
true, overwrite_mode);
} else {
// Set the flags based on the operation, type and loop nesting level.
- // Bit operations always assume they likely operate on Smis. Still only
+ // Bit operations always assume they likely operate on smis. Still only
// generate the inline Smi check code if this operation is part of a loop.
// For all other operations only inline the Smi check code for likely smis
// if the operation is part of a loop.
@@ -2106,7 +2112,7 @@
if (cc == equal) {
Label comparison_done;
__ SmiCompare(FieldOperand(left_side.reg(), String::kLengthOffset),
- Smi::FromInt(1));
+ Smi::FromInt(1));
__ j(not_equal, &comparison_done);
uint8_t char_value =
static_cast<uint8_t>(String::cast(*right_val)->Get(0));
@@ -2292,7 +2298,7 @@
// CompareStub and the inline code both support all values of cc.
}
// Implement comparison against a constant Smi, inlining the case
- // where both sides are Smis.
+ // where both sides are smis.
left_side->ToRegister();
Register left_reg = left_side->reg();
Smi* constant_smi = Smi::cast(*right_side->handle());
@@ -2302,7 +2308,6 @@
__ AbortIfNotSmi(left_reg);
}
// Test smi equality and comparison by signed int comparison.
- // Both sides are smis, so we can use an Immediate.
__ SmiCompare(left_reg, constant_smi);
left_side->Unuse();
right_side->Unuse();
@@ -2312,7 +2317,7 @@
JumpTarget is_smi;
if (cc == equal) {
// We can do the equality comparison before the smi check.
- __ SmiCompare(left_reg, constant_smi);
+ __ Cmp(left_reg, constant_smi);
dest->true_target()->Branch(equal);
Condition left_is_smi = masm_->CheckSmi(left_reg);
dest->false_target()->Branch(left_is_smi);
@@ -2573,8 +2578,8 @@
// adaptor frame below it.
Label invoke, adapted;
__ movq(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
- __ SmiCompare(Operand(rdx, StandardFrameConstants::kContextOffset),
- Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
+ __ Cmp(Operand(rdx, StandardFrameConstants::kContextOffset),
+ Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
__ j(equal, &adapted);
// No arguments adaptor frame. Copy fixed number of arguments.
@@ -2751,7 +2756,8 @@
frame_->EmitPush(rsi); // The context is the first argument.
frame_->EmitPush(kScratchRegister);
frame_->EmitPush(Smi::FromInt(is_eval() ? 1 : 0));
- Result ignored = frame_->CallRuntime(Runtime::kDeclareGlobals, 3);
+ frame_->EmitPush(Smi::FromInt(strict_mode_flag()));
+ Result ignored = frame_->CallRuntime(Runtime::kDeclareGlobals, 4);
// Return value is ignored.
}
@@ -3854,7 +3860,7 @@
__ movq(rbx, rax);
// If the property has been removed while iterating, we just skip it.
- __ SmiCompare(rbx, Smi::FromInt(0));
+ __ Cmp(rbx, Smi::FromInt(0));
node->continue_target()->Branch(equal);
end_del_check.Bind();
@@ -4609,7 +4615,8 @@
// by initialization.
value = frame_->CallRuntime(Runtime::kInitializeConstContextSlot, 3);
} else {
- value = frame_->CallRuntime(Runtime::kStoreContextSlot, 3);
+ frame_->Push(Smi::FromInt(strict_mode_flag()));
+ value = frame_->CallRuntime(Runtime::kStoreContextSlot, 4);
}
// Storing a variable must keep the (new) value on the expression
// stack. This is necessary for compiling chained assignment
@@ -4922,8 +4929,9 @@
Load(property->key());
Load(property->value());
if (property->emit_store()) {
+ frame_->Push(Smi::FromInt(NONE)); // PropertyAttributes
// Ignore the result.
- Result ignored = frame_->CallRuntime(Runtime::kSetProperty, 3);
+ Result ignored = frame_->CallRuntime(Runtime::kSetProperty, 4);
} else {
frame_->Drop(3);
}
@@ -6201,15 +6209,15 @@
// Skip the arguments adaptor frame if it exists.
Label check_frame_marker;
- __ SmiCompare(Operand(fp.reg(), StandardFrameConstants::kContextOffset),
- Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
+ __ Cmp(Operand(fp.reg(), StandardFrameConstants::kContextOffset),
+ Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
__ j(not_equal, &check_frame_marker);
__ movq(fp.reg(), Operand(fp.reg(), StandardFrameConstants::kCallerFPOffset));
// Check the marker in the calling frame.
__ bind(&check_frame_marker);
- __ SmiCompare(Operand(fp.reg(), StandardFrameConstants::kMarkerOffset),
- Smi::FromInt(StackFrame::CONSTRUCT));
+ __ Cmp(Operand(fp.reg(), StandardFrameConstants::kMarkerOffset),
+ Smi::FromInt(StackFrame::CONSTRUCT));
fp.Unuse();
destination()->Split(equal);
}
@@ -6229,8 +6237,8 @@
// Check if the calling frame is an arguments adaptor frame.
__ movq(fp.reg(), Operand(rbp, StandardFrameConstants::kCallerFPOffset));
- __ SmiCompare(Operand(fp.reg(), StandardFrameConstants::kContextOffset),
- Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
+ __ Cmp(Operand(fp.reg(), StandardFrameConstants::kContextOffset),
+ Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
__ j(not_equal, &exit);
// Arguments adaptor case: Read the arguments length from the
@@ -6789,8 +6797,8 @@
// Fetch the map and check if array is in fast case.
// Check that object doesn't require security checks and
// has no indexed interceptor.
- __ CmpObjectType(object.reg(), FIRST_JS_OBJECT_TYPE, tmp1.reg());
- deferred->Branch(below);
+ __ CmpObjectType(object.reg(), JS_ARRAY_TYPE, tmp1.reg());
+ deferred->Branch(not_equal);
__ testb(FieldOperand(tmp1.reg(), Map::kBitFieldOffset),
Immediate(KeyedLoadIC::kSlowCaseBitFieldMask));
deferred->Branch(not_zero);
@@ -6832,7 +6840,7 @@
Label done;
__ InNewSpace(tmp1.reg(), tmp2.reg(), equal, &done);
- // Possible optimization: do a check that both values are Smis
+ // Possible optimization: do a check that both values are smis
// (or them and test against Smi mask.)
__ movq(tmp2.reg(), tmp1.reg());
@@ -7045,7 +7053,8 @@
void CodeGenerator::GenerateMathSin(ZoneList<Expression*>* args) {
ASSERT_EQ(args->length(), 1);
Load(args->at(0));
- TranscendentalCacheStub stub(TranscendentalCache::SIN);
+ TranscendentalCacheStub stub(TranscendentalCache::SIN,
+ TranscendentalCacheStub::TAGGED);
Result result = frame_->CallStub(&stub, 1);
frame_->Push(&result);
}
@@ -7054,7 +7063,8 @@
void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) {
ASSERT_EQ(args->length(), 1);
Load(args->at(0));
- TranscendentalCacheStub stub(TranscendentalCache::COS);
+ TranscendentalCacheStub stub(TranscendentalCache::COS,
+ TranscendentalCacheStub::TAGGED);
Result result = frame_->CallStub(&stub, 1);
frame_->Push(&result);
}
@@ -7063,7 +7073,8 @@
void CodeGenerator::GenerateMathLog(ZoneList<Expression*>* args) {
ASSERT_EQ(args->length(), 1);
Load(args->at(0));
- TranscendentalCacheStub stub(TranscendentalCache::LOG);
+ TranscendentalCacheStub stub(TranscendentalCache::LOG,
+ TranscendentalCacheStub::TAGGED);
Result result = frame_->CallStub(&stub, 1);
frame_->Push(&result);
}
@@ -7254,8 +7265,8 @@
Variable* variable = node->expression()->AsVariableProxy()->AsVariable();
if (variable != NULL) {
// Delete of an unqualified identifier is disallowed in strict mode
- // so this code can only be reached in non-strict mode.
- ASSERT(strict_mode_flag() == kNonStrictMode);
+ // but "delete this" is.
+ ASSERT(strict_mode_flag() == kNonStrictMode || variable->is_this());
Slot* slot = variable->AsSlot();
if (variable->is_global()) {
LoadGlobal();
@@ -7264,7 +7275,6 @@
Result answer = frame_->InvokeBuiltin(Builtins::DELETE,
CALL_FUNCTION, 3);
frame_->Push(&answer);
- return;
} else if (slot != NULL && slot->type() == Slot::LOOKUP) {
// Call the runtime to delete from the context holding the named
@@ -7275,13 +7285,11 @@
frame_->EmitPush(variable->name());
Result answer = frame_->CallRuntime(Runtime::kDeleteContextSlot, 2);
frame_->Push(&answer);
- return;
+ } else {
+ // Default: Result of deleting non-global, not dynamically
+ // introduced variables is false.
+ frame_->Push(Factory::false_value());
}
-
- // Default: Result of deleting non-global, not dynamically
- // introduced variables is false.
- frame_->Push(Factory::false_value());
-
} else {
// Default: Result of deleting expressions is true.
Load(node->expression()); // may have side-effects
@@ -7967,7 +7975,7 @@
&& (allocator()->count(r9) == (frame()->is_used(r9) ? 1 : 0))
&& (allocator()->count(r11) == (frame()->is_used(r11) ? 1 : 0))
&& (allocator()->count(r14) == (frame()->is_used(r14) ? 1 : 0))
- && (allocator()->count(r12) == (frame()->is_used(r12) ? 1 : 0));
+ && (allocator()->count(r15) == (frame()->is_used(r15) ? 1 : 0));
}
#endif
@@ -8090,8 +8098,12 @@
public:
DeferredReferenceSetKeyedValue(Register value,
Register key,
- Register receiver)
- : value_(value), key_(key), receiver_(receiver) {
+ Register receiver,
+ StrictModeFlag strict_mode)
+ : value_(value),
+ key_(key),
+ receiver_(receiver),
+ strict_mode_(strict_mode) {
set_comment("[ DeferredReferenceSetKeyedValue");
}
@@ -8104,6 +8116,7 @@
Register key_;
Register receiver_;
Label patch_site_;
+ StrictModeFlag strict_mode_;
};
@@ -8155,7 +8168,9 @@
}
// Call the IC stub.
- Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
+ Handle<Code> ic(Builtins::builtin(
+ (strict_mode_ == kStrictMode) ? Builtins::KeyedStoreIC_Initialize_Strict
+ : Builtins::KeyedStoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
// The delta from the start of the map-compare instructions (initial movq)
// to the test instruction. We use masm_-> directly here instead of the
@@ -8222,7 +8237,8 @@
// This is the map check instruction that will be patched (so we can't
// use the double underscore macro that may insert instructions).
// Initially use an invalid map to force a failure.
- masm()->Move(kScratchRegister, Factory::null_value());
+ masm()->movq(kScratchRegister, Factory::null_value(),
+ RelocInfo::EMBEDDED_OBJECT);
masm()->cmpq(FieldOperand(receiver.reg(), HeapObject::kMapOffset),
kScratchRegister);
// This branch is always a forwards branch so it's always a fixed
@@ -8298,7 +8314,8 @@
// the __ macro for the following two instructions because it
// might introduce extra instructions.
__ bind(&patch_site);
- masm()->Move(kScratchRegister, Factory::null_value());
+ masm()->movq(kScratchRegister, Factory::null_value(),
+ RelocInfo::EMBEDDED_OBJECT);
masm()->cmpq(FieldOperand(receiver.reg(), HeapObject::kMapOffset),
kScratchRegister);
// This branch is always a forwards branch so it's always a fixed size
@@ -8499,7 +8516,8 @@
DeferredReferenceSetKeyedValue* deferred =
new DeferredReferenceSetKeyedValue(result.reg(),
key.reg(),
- receiver.reg());
+ receiver.reg(),
+ strict_mode_flag());
// Check that the receiver is not a smi.
__ JumpIfSmi(receiver.reg(), deferred->entry_label());
@@ -8515,12 +8533,6 @@
__ CmpObjectType(receiver.reg(), JS_ARRAY_TYPE, kScratchRegister);
deferred->Branch(not_equal);
- // Check that the key is within bounds. Both the key and the length of
- // the JSArray are smis. Use unsigned comparison to handle negative keys.
- __ SmiCompare(FieldOperand(receiver.reg(), JSArray::kLengthOffset),
- key.reg());
- deferred->Branch(below_equal);
-
// Get the elements array from the receiver and check that it is not a
// dictionary.
__ movq(tmp.reg(),
@@ -8550,6 +8562,14 @@
kScratchRegister);
deferred->Branch(not_equal);
+ // Check that the key is within bounds. Both the key and the length of
+ // the JSArray are smis (because the fixed array check above ensures the
+ // elements are in fast case). Use unsigned comparison to handle negative
+ // keys.
+ __ SmiCompare(FieldOperand(receiver.reg(), JSArray::kLengthOffset),
+ key.reg());
+ deferred->Branch(below_equal);
+
// Store the value.
SmiIndex index =
masm()->SmiToIndex(kScratchRegister, key.reg(), kPointerSizeLog2);
@@ -8562,7 +8582,7 @@
deferred->BindExit();
} else {
- result = frame()->CallKeyedStoreIC();
+ result = frame()->CallKeyedStoreIC(strict_mode_flag());
// Make sure that we do not have a test instruction after the
// call. A test instruction after the call is used to
// indicate that we have generated an inline version of the
« no previous file with comments | « src/x64/codegen-x64.h ('k') | src/x64/codegen-x64-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698