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

Unified Diff: src/ia32/codegen-ia32.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/ia32/code-stubs-ia32.cc ('k') | src/ia32/deoptimizer-ia32.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ia32/codegen-ia32.cc
===================================================================
--- src/ia32/codegen-ia32.cc (revision 7180)
+++ src/ia32/codegen-ia32.cc (working copy)
@@ -733,11 +733,14 @@
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;
}
@@ -764,8 +767,11 @@
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) {
@@ -788,7 +794,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();
}
@@ -3530,7 +3538,8 @@
frame_->EmitPush(esi); // The context is the first argument.
frame_->EmitPush(Immediate(pairs));
frame_->EmitPush(Immediate(Smi::FromInt(is_eval() ? 1 : 0)));
- Result ignored = frame_->CallRuntime(Runtime::kDeclareGlobals, 3);
+ frame_->EmitPush(Immediate(Smi::FromInt(strict_mode_flag())));
+ Result ignored = frame_->CallRuntime(Runtime::kDeclareGlobals, 4);
// Return value is ignored.
}
@@ -5263,7 +5272,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
@@ -5369,10 +5379,20 @@
void CodeGenerator::VisitLiteral(Literal* node) {
Comment cmnt(masm_, "[ Literal");
- if (in_safe_int32_mode()) {
- frame_->PushUntaggedElement(node->handle());
+ if (frame_->ConstantPoolOverflowed()) {
+ Result temp = allocator_->Allocate();
+ ASSERT(temp.is_valid());
+ if (in_safe_int32_mode()) {
+ temp.set_untagged_int32(true);
+ }
+ __ Set(temp.reg(), Immediate(node->handle()));
+ frame_->Push(&temp);
} else {
- frame_->Push(node->handle());
+ if (in_safe_int32_mode()) {
+ frame_->PushUntaggedElement(node->handle());
+ } else {
+ frame_->Push(node->handle());
+ }
}
}
@@ -5617,8 +5637,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);
}
@@ -8249,8 +8270,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();
@@ -8259,7 +8280,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
@@ -8270,13 +8290,11 @@
frame_->EmitPush(Immediate(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
@@ -8318,6 +8336,7 @@
switch (op) {
case Token::SUB: {
__ neg(value.reg());
+ frame_->Push(&value);
if (node->no_negative_zero()) {
// -MIN_INT is MIN_INT with the overflow flag set.
unsafe_bailout_->Branch(overflow);
@@ -8330,17 +8349,18 @@
}
case Token::BIT_NOT: {
__ not_(value.reg());
+ frame_->Push(&value);
break;
}
case Token::ADD: {
// Unary plus has no effect on int32 values.
+ frame_->Push(&value);
break;
}
default:
UNREACHABLE();
break;
}
- frame_->Push(&value);
} else {
Load(node->expression());
bool can_overwrite = node->expression()->ResultOverwriteAllowed();
@@ -9476,11 +9496,13 @@
DeferredReferenceSetKeyedValue(Register value,
Register key,
Register receiver,
- Register scratch)
+ Register scratch,
+ StrictModeFlag strict_mode)
: value_(value),
key_(key),
receiver_(receiver),
- scratch_(scratch) {
+ scratch_(scratch),
+ strict_mode_(strict_mode) {
set_comment("[ DeferredReferenceSetKeyedValue");
}
@@ -9494,6 +9516,7 @@
Register receiver_;
Register scratch_;
Label patch_site_;
+ StrictModeFlag strict_mode_;
};
@@ -9552,7 +9575,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 instruction to the
// test instruction. We use masm_-> directly here instead of the
@@ -9917,7 +9942,8 @@
new DeferredReferenceSetKeyedValue(result.reg(),
key.reg(),
receiver.reg(),
- tmp.reg());
+ tmp.reg(),
+ strict_mode_flag());
// Check that the receiver is not a smi.
__ test(receiver.reg(), Immediate(kSmiTagMask));
@@ -9935,12 +9961,6 @@
__ CmpObjectType(receiver.reg(), JS_ARRAY_TYPE, tmp.reg());
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.
- __ cmp(key.reg(),
- FieldOperand(receiver.reg(), JSArray::kLengthOffset));
- deferred->Branch(above_equal);
-
// Get the elements array from the receiver and check that it is not a
// dictionary.
__ mov(tmp.reg(),
@@ -9967,13 +9987,21 @@
Immediate(Factory::fixed_array_map()));
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.
+ __ cmp(key.reg(),
+ FieldOperand(receiver.reg(), JSArray::kLengthOffset));
+ deferred->Branch(above_equal);
+
// Store the value.
__ mov(FixedArrayElementOperand(tmp.reg(), key.reg()), result.reg());
__ IncrementCounter(&Counters::keyed_store_inline, 1);
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/ia32/code-stubs-ia32.cc ('k') | src/ia32/deoptimizer-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698