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

Side by Side Diff: src/ia32/codegen-ia32.cc

Issue 6614010: [Isolates] Merge 6700:7030 from bleeding_edge to isolates. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/code-stubs-ia32.cc ('k') | src/ia32/deoptimizer-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 3513 matching lines...) Expand 10 before | Expand all | Expand 10 after
3524 3524
3525 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 3525 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
3526 // Call the runtime to declare the globals. The inevitable call 3526 // Call the runtime to declare the globals. The inevitable call
3527 // will sync frame elements to memory anyway, so we do it eagerly to 3527 // will sync frame elements to memory anyway, so we do it eagerly to
3528 // allow us to push the arguments directly into place. 3528 // allow us to push the arguments directly into place.
3529 frame_->SyncRange(0, frame_->element_count() - 1); 3529 frame_->SyncRange(0, frame_->element_count() - 1);
3530 3530
3531 frame_->EmitPush(esi); // The context is the first argument. 3531 frame_->EmitPush(esi); // The context is the first argument.
3532 frame_->EmitPush(Immediate(pairs)); 3532 frame_->EmitPush(Immediate(pairs));
3533 frame_->EmitPush(Immediate(Smi::FromInt(is_eval() ? 1 : 0))); 3533 frame_->EmitPush(Immediate(Smi::FromInt(is_eval() ? 1 : 0)));
3534 Result ignored = frame_->CallRuntime(Runtime::kDeclareGlobals, 3); 3534 frame_->EmitPush(Immediate(Smi::FromInt(strict_mode_flag())));
3535 Result ignored = frame_->CallRuntime(Runtime::kDeclareGlobals, 4);
3535 // Return value is ignored. 3536 // Return value is ignored.
3536 } 3537 }
3537 3538
3538 3539
3539 void CodeGenerator::VisitDeclaration(Declaration* node) { 3540 void CodeGenerator::VisitDeclaration(Declaration* node) {
3540 Comment cmnt(masm_, "[ Declaration"); 3541 Comment cmnt(masm_, "[ Declaration");
3541 Variable* var = node->proxy()->var(); 3542 Variable* var = node->proxy()->var();
3542 ASSERT(var != NULL); // must have been resolved 3543 ASSERT(var != NULL); // must have been resolved
3543 Slot* slot = var->AsSlot(); 3544 Slot* slot = var->AsSlot();
3544 3545
(...skipping 1712 matching lines...) Expand 10 before | Expand all | Expand 10 after
5257 // context slot declaration, but we cannot initialize it at the same 5258 // context slot declaration, but we cannot initialize it at the same
5258 // time, because the const declaration may be at the end of the eval 5259 // time, because the const declaration may be at the end of the eval
5259 // code (sigh...) and the const variable may have been used before 5260 // code (sigh...) and the const variable may have been used before
5260 // (where its value is 'undefined'). Thus, we can only do the 5261 // (where its value is 'undefined'). Thus, we can only do the
5261 // initialization when we actually encounter the expression and when 5262 // initialization when we actually encounter the expression and when
5262 // the expression operands are defined and valid, and thus we need the 5263 // the expression operands are defined and valid, and thus we need the
5263 // split into 2 operations: declaration of the context slot followed 5264 // split into 2 operations: declaration of the context slot followed
5264 // by initialization. 5265 // by initialization.
5265 value = frame_->CallRuntime(Runtime::kInitializeConstContextSlot, 3); 5266 value = frame_->CallRuntime(Runtime::kInitializeConstContextSlot, 3);
5266 } else { 5267 } else {
5267 value = frame_->CallRuntime(Runtime::kStoreContextSlot, 3); 5268 frame_->Push(Smi::FromInt(strict_mode_flag()));
5269 value = frame_->CallRuntime(Runtime::kStoreContextSlot, 4);
5268 } 5270 }
5269 // Storing a variable must keep the (new) value on the expression 5271 // Storing a variable must keep the (new) value on the expression
5270 // stack. This is necessary for compiling chained assignment 5272 // stack. This is necessary for compiling chained assignment
5271 // expressions. 5273 // expressions.
5272 frame_->Push(&value); 5274 frame_->Push(&value);
5273 5275
5274 } else { 5276 } else {
5275 ASSERT(!slot->var()->is_dynamic()); 5277 ASSERT(!slot->var()->is_dynamic());
5276 5278
5277 JumpTarget exit; 5279 JumpTarget exit;
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
5358 ASSERT(var->is_global()); 5360 ASSERT(var->is_global());
5359 ASSERT(!in_safe_int32_mode()); 5361 ASSERT(!in_safe_int32_mode());
5360 Reference ref(this, node); 5362 Reference ref(this, node);
5361 ref.GetValue(); 5363 ref.GetValue();
5362 } 5364 }
5363 } 5365 }
5364 5366
5365 5367
5366 void CodeGenerator::VisitLiteral(Literal* node) { 5368 void CodeGenerator::VisitLiteral(Literal* node) {
5367 Comment cmnt(masm_, "[ Literal"); 5369 Comment cmnt(masm_, "[ Literal");
5368 if (in_safe_int32_mode()) { 5370 if (frame_->ConstantPoolOverflowed()) {
5369 frame_->PushUntaggedElement(node->handle()); 5371 Result temp = allocator_->Allocate();
5372 ASSERT(temp.is_valid());
5373 if (in_safe_int32_mode()) {
5374 temp.set_untagged_int32(true);
5375 }
5376 __ Set(temp.reg(), Immediate(node->handle()));
5377 frame_->Push(&temp);
5370 } else { 5378 } else {
5371 frame_->Push(node->handle()); 5379 if (in_safe_int32_mode()) {
5380 frame_->PushUntaggedElement(node->handle());
5381 } else {
5382 frame_->Push(node->handle());
5383 }
5372 } 5384 }
5373 } 5385 }
5374 5386
5375 5387
5376 void CodeGenerator::PushUnsafeSmi(Handle<Object> value) { 5388 void CodeGenerator::PushUnsafeSmi(Handle<Object> value) {
5377 ASSERT(value->IsSmi()); 5389 ASSERT(value->IsSmi());
5378 int bits = reinterpret_cast<int>(*value); 5390 int bits = reinterpret_cast<int>(*value);
5379 __ push(Immediate(bits ^ jit_cookie_)); 5391 __ push(Immediate(bits ^ jit_cookie_));
5380 __ xor_(Operand(esp, 0), Immediate(jit_cookie_)); 5392 __ xor_(Operand(esp, 0), Immediate(jit_cookie_));
5381 } 5393 }
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
5586 if (CompileTimeValue::IsCompileTimeValue(property->value())) break; 5598 if (CompileTimeValue::IsCompileTimeValue(property->value())) break;
5587 // else fall through. 5599 // else fall through.
5588 case ObjectLiteral::Property::COMPUTED: { 5600 case ObjectLiteral::Property::COMPUTED: {
5589 Handle<Object> key(property->key()->handle()); 5601 Handle<Object> key(property->key()->handle());
5590 if (key->IsSymbol()) { 5602 if (key->IsSymbol()) {
5591 // Duplicate the object as the IC receiver. 5603 // Duplicate the object as the IC receiver.
5592 frame_->Dup(); 5604 frame_->Dup();
5593 Load(property->value()); 5605 Load(property->value());
5594 if (property->emit_store()) { 5606 if (property->emit_store()) {
5595 Result ignored = 5607 Result ignored =
5596 frame_->CallStoreIC(Handle<String>::cast(key), false); 5608 frame_->CallStoreIC(Handle<String>::cast(key), false,
5609 strict_mode_flag());
5597 // A test eax instruction following the store IC call would 5610 // A test eax instruction following the store IC call would
5598 // indicate the presence of an inlined version of the 5611 // indicate the presence of an inlined version of the
5599 // store. Add a nop to indicate that there is no such 5612 // store. Add a nop to indicate that there is no such
5600 // inlined version. 5613 // inlined version.
5601 __ nop(); 5614 __ nop();
5602 } else { 5615 } else {
5603 frame_->Drop(2); 5616 frame_->Drop(2);
5604 } 5617 }
5605 break; 5618 break;
5606 } 5619 }
5607 // Fall through 5620 // Fall through
5608 } 5621 }
5609 case ObjectLiteral::Property::PROTOTYPE: { 5622 case ObjectLiteral::Property::PROTOTYPE: {
5610 // Duplicate the object as an argument to the runtime call. 5623 // Duplicate the object as an argument to the runtime call.
5611 frame_->Dup(); 5624 frame_->Dup();
5612 Load(property->key()); 5625 Load(property->key());
5613 Load(property->value()); 5626 Load(property->value());
5614 if (property->emit_store()) { 5627 if (property->emit_store()) {
5628 frame_->Push(Smi::FromInt(NONE)); // PropertyAttributes
5615 // Ignore the result. 5629 // Ignore the result.
5616 Result ignored = frame_->CallRuntime(Runtime::kSetProperty, 3); 5630 Result ignored = frame_->CallRuntime(Runtime::kSetProperty, 4);
5617 } else { 5631 } else {
5618 frame_->Drop(3); 5632 frame_->Drop(3);
5619 } 5633 }
5620 break; 5634 break;
5621 } 5635 }
5622 case ObjectLiteral::Property::SETTER: { 5636 case ObjectLiteral::Property::SETTER: {
5623 // Duplicate the object as an argument to the runtime call. 5637 // Duplicate the object as an argument to the runtime call.
5624 frame_->Dup(); 5638 frame_->Dup();
5625 Load(property->key()); 5639 Load(property->key());
5626 frame_->Push(Smi::FromInt(1)); 5640 frame_->Push(Smi::FromInt(1));
(...skipping 2595 matching lines...) Expand 10 before | Expand all | Expand 10 after
8222 destination()->Invert(); 8236 destination()->Invert();
8223 LoadCondition(node->expression(), destination(), true); 8237 LoadCondition(node->expression(), destination(), true);
8224 // Swap the labels back. 8238 // Swap the labels back.
8225 destination()->Invert(); 8239 destination()->Invert();
8226 8240
8227 } else if (op == Token::DELETE) { 8241 } else if (op == Token::DELETE) {
8228 Property* property = node->expression()->AsProperty(); 8242 Property* property = node->expression()->AsProperty();
8229 if (property != NULL) { 8243 if (property != NULL) {
8230 Load(property->obj()); 8244 Load(property->obj());
8231 Load(property->key()); 8245 Load(property->key());
8232 Result answer = frame_->InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, 2); 8246 frame_->Push(Smi::FromInt(strict_mode_flag()));
8247 Result answer = frame_->InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, 3);
8233 frame_->Push(&answer); 8248 frame_->Push(&answer);
8234 return; 8249 return;
8235 } 8250 }
8236 8251
8237 Variable* variable = node->expression()->AsVariableProxy()->AsVariable(); 8252 Variable* variable = node->expression()->AsVariableProxy()->AsVariable();
8238 if (variable != NULL) { 8253 if (variable != NULL) {
8254 // Delete of an unqualified identifier is disallowed in strict mode
8255 // but "delete this" is.
8256 ASSERT(strict_mode_flag() == kNonStrictMode || variable->is_this());
8239 Slot* slot = variable->AsSlot(); 8257 Slot* slot = variable->AsSlot();
8240 if (variable->is_global()) { 8258 if (variable->is_global()) {
8241 LoadGlobal(); 8259 LoadGlobal();
8242 frame_->Push(variable->name()); 8260 frame_->Push(variable->name());
8261 frame_->Push(Smi::FromInt(kNonStrictMode));
8243 Result answer = frame_->InvokeBuiltin(Builtins::DELETE, 8262 Result answer = frame_->InvokeBuiltin(Builtins::DELETE,
8244 CALL_FUNCTION, 2); 8263 CALL_FUNCTION, 3);
8245 frame_->Push(&answer); 8264 frame_->Push(&answer);
8246 return;
8247 8265
8248 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { 8266 } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
8249 // Call the runtime to delete from the context holding the named 8267 // Call the runtime to delete from the context holding the named
8250 // variable. Sync the virtual frame eagerly so we can push the 8268 // variable. Sync the virtual frame eagerly so we can push the
8251 // arguments directly into place. 8269 // arguments directly into place.
8252 frame_->SyncRange(0, frame_->element_count() - 1); 8270 frame_->SyncRange(0, frame_->element_count() - 1);
8253 frame_->EmitPush(esi); 8271 frame_->EmitPush(esi);
8254 frame_->EmitPush(Immediate(variable->name())); 8272 frame_->EmitPush(Immediate(variable->name()));
8255 Result answer = frame_->CallRuntime(Runtime::kDeleteContextSlot, 2); 8273 Result answer = frame_->CallRuntime(Runtime::kDeleteContextSlot, 2);
8256 frame_->Push(&answer); 8274 frame_->Push(&answer);
8257 return; 8275 } else {
8276 // Default: Result of deleting non-global, not dynamically
8277 // introduced variables is false.
8278 frame_->Push(FACTORY->false_value());
8258 } 8279 }
8259
8260 // Default: Result of deleting non-global, not dynamically
8261 // introduced variables is false.
8262 frame_->Push(FACTORY->false_value());
8263
8264 } else { 8280 } else {
8265 // Default: Result of deleting expressions is true. 8281 // Default: Result of deleting expressions is true.
8266 Load(node->expression()); // may have side-effects 8282 Load(node->expression()); // may have side-effects
8267 frame_->SetElementAt(0, FACTORY->true_value()); 8283 frame_->SetElementAt(0, FACTORY->true_value());
8268 } 8284 }
8269 8285
8270 } else if (op == Token::TYPEOF) { 8286 } else if (op == Token::TYPEOF) {
8271 // Special case for loading the typeof expression; see comment on 8287 // Special case for loading the typeof expression; see comment on
8272 // LoadTypeofExpression(). 8288 // LoadTypeofExpression().
8273 LoadTypeofExpression(node->expression()); 8289 LoadTypeofExpression(node->expression());
(...skipping 21 matching lines...) Expand all
8295 if (in_safe_int32_mode()) { 8311 if (in_safe_int32_mode()) {
8296 Visit(node->expression()); 8312 Visit(node->expression());
8297 Result value = frame_->Pop(); 8313 Result value = frame_->Pop();
8298 ASSERT(value.is_untagged_int32()); 8314 ASSERT(value.is_untagged_int32());
8299 // Registers containing an int32 value are not multiply used. 8315 // Registers containing an int32 value are not multiply used.
8300 ASSERT(!value.is_register() || !frame_->is_used(value.reg())); 8316 ASSERT(!value.is_register() || !frame_->is_used(value.reg()));
8301 value.ToRegister(); 8317 value.ToRegister();
8302 switch (op) { 8318 switch (op) {
8303 case Token::SUB: { 8319 case Token::SUB: {
8304 __ neg(value.reg()); 8320 __ neg(value.reg());
8321 frame_->Push(&value);
8305 if (node->no_negative_zero()) { 8322 if (node->no_negative_zero()) {
8306 // -MIN_INT is MIN_INT with the overflow flag set. 8323 // -MIN_INT is MIN_INT with the overflow flag set.
8307 unsafe_bailout_->Branch(overflow); 8324 unsafe_bailout_->Branch(overflow);
8308 } else { 8325 } else {
8309 // MIN_INT and 0 both have bad negations. They both have 31 zeros. 8326 // MIN_INT and 0 both have bad negations. They both have 31 zeros.
8310 __ test(value.reg(), Immediate(0x7FFFFFFF)); 8327 __ test(value.reg(), Immediate(0x7FFFFFFF));
8311 unsafe_bailout_->Branch(zero); 8328 unsafe_bailout_->Branch(zero);
8312 } 8329 }
8313 break; 8330 break;
8314 } 8331 }
8315 case Token::BIT_NOT: { 8332 case Token::BIT_NOT: {
8316 __ not_(value.reg()); 8333 __ not_(value.reg());
8334 frame_->Push(&value);
8317 break; 8335 break;
8318 } 8336 }
8319 case Token::ADD: { 8337 case Token::ADD: {
8320 // Unary plus has no effect on int32 values. 8338 // Unary plus has no effect on int32 values.
8339 frame_->Push(&value);
8321 break; 8340 break;
8322 } 8341 }
8323 default: 8342 default:
8324 UNREACHABLE(); 8343 UNREACHABLE();
8325 break; 8344 break;
8326 } 8345 }
8327 frame_->Push(&value);
8328 } else { 8346 } else {
8329 Load(node->expression()); 8347 Load(node->expression());
8330 bool can_overwrite = node->expression()->ResultOverwriteAllowed(); 8348 bool can_overwrite = node->expression()->ResultOverwriteAllowed();
8331 UnaryOverwriteMode overwrite = 8349 UnaryOverwriteMode overwrite =
8332 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; 8350 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE;
8333 bool no_negative_zero = node->expression()->no_negative_zero(); 8351 bool no_negative_zero = node->expression()->no_negative_zero();
8334 switch (op) { 8352 switch (op) {
8335 case Token::NOT: 8353 case Token::NOT:
8336 case Token::DELETE: 8354 case Token::DELETE:
8337 case Token::TYPEOF: 8355 case Token::TYPEOF:
(...skipping 1117 matching lines...) Expand 10 before | Expand all | Expand 10 after
9455 9473
9456 if (!dst_.is(eax)) __ mov(dst_, eax); 9474 if (!dst_.is(eax)) __ mov(dst_, eax);
9457 } 9475 }
9458 9476
9459 9477
9460 class DeferredReferenceSetKeyedValue: public DeferredCode { 9478 class DeferredReferenceSetKeyedValue: public DeferredCode {
9461 public: 9479 public:
9462 DeferredReferenceSetKeyedValue(Register value, 9480 DeferredReferenceSetKeyedValue(Register value,
9463 Register key, 9481 Register key,
9464 Register receiver, 9482 Register receiver,
9465 Register scratch) 9483 Register scratch,
9484 StrictModeFlag strict_mode)
9466 : value_(value), 9485 : value_(value),
9467 key_(key), 9486 key_(key),
9468 receiver_(receiver), 9487 receiver_(receiver),
9469 scratch_(scratch) { 9488 scratch_(scratch),
9489 strict_mode_(strict_mode) {
9470 set_comment("[ DeferredReferenceSetKeyedValue"); 9490 set_comment("[ DeferredReferenceSetKeyedValue");
9471 } 9491 }
9472 9492
9473 virtual void Generate(); 9493 virtual void Generate();
9474 9494
9475 Label* patch_site() { return &patch_site_; } 9495 Label* patch_site() { return &patch_site_; }
9476 9496
9477 private: 9497 private:
9478 Register value_; 9498 Register value_;
9479 Register key_; 9499 Register key_;
9480 Register receiver_; 9500 Register receiver_;
9481 Register scratch_; 9501 Register scratch_;
9482 Label patch_site_; 9502 Label patch_site_;
9503 StrictModeFlag strict_mode_;
9483 }; 9504 };
9484 9505
9485 9506
9486 void DeferredReferenceSetKeyedValue::Generate() { 9507 void DeferredReferenceSetKeyedValue::Generate() {
9487 __ IncrementCounter(COUNTERS->keyed_store_inline_miss(), 1); 9508 __ IncrementCounter(COUNTERS->keyed_store_inline_miss(), 1);
9488 // Move value_ to eax, key_ to ecx, and receiver_ to edx. 9509 // Move value_ to eax, key_ to ecx, and receiver_ to edx.
9489 Register old_value = value_; 9510 Register old_value = value_;
9490 9511
9491 // First, move value to eax. 9512 // First, move value to eax.
9492 if (!value_.is(eax)) { 9513 if (!value_.is(eax)) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
9532 } 9553 }
9533 } else { // Key is not in edx or ecx. 9554 } else { // Key is not in edx or ecx.
9534 if (!receiver_.is(edx)) { 9555 if (!receiver_.is(edx)) {
9535 __ mov(edx, receiver_); 9556 __ mov(edx, receiver_);
9536 } 9557 }
9537 __ mov(ecx, key_); 9558 __ mov(ecx, key_);
9538 } 9559 }
9539 9560
9540 // Call the IC stub. 9561 // Call the IC stub.
9541 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 9562 Handle<Code> ic(Isolate::Current()->builtins()->builtin(
9542 Builtins::KeyedStoreIC_Initialize)); 9563 (strict_mode_ == kStrictMode) ? Builtins::KeyedStoreIC_Initialize_Strict
9564 : Builtins::KeyedStoreIC_Initialize));
9543 __ call(ic, RelocInfo::CODE_TARGET); 9565 __ call(ic, RelocInfo::CODE_TARGET);
9544 // The delta from the start of the map-compare instruction to the 9566 // The delta from the start of the map-compare instruction to the
9545 // test instruction. We use masm_-> directly here instead of the 9567 // test instruction. We use masm_-> directly here instead of the
9546 // __ macro because the macro sometimes uses macro expansion to turn 9568 // __ macro because the macro sometimes uses macro expansion to turn
9547 // into something that can't return a value. This is encountered 9569 // into something that can't return a value. This is encountered
9548 // when doing generated code coverage tests. 9570 // when doing generated code coverage tests.
9549 int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(patch_site()); 9571 int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(patch_site());
9550 // Here we use masm_-> instead of the __ macro because this is the 9572 // Here we use masm_-> instead of the __ macro because this is the
9551 // instruction that gets patched and coverage code gets in the way. 9573 // instruction that gets patched and coverage code gets in the way.
9552 masm_->test(eax, Immediate(-delta_to_patch_site)); 9574 masm_->test(eax, Immediate(-delta_to_patch_site));
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
9674 } 9696 }
9675 9697
9676 9698
9677 Result CodeGenerator::EmitNamedStore(Handle<String> name, bool is_contextual) { 9699 Result CodeGenerator::EmitNamedStore(Handle<String> name, bool is_contextual) {
9678 #ifdef DEBUG 9700 #ifdef DEBUG
9679 int expected_height = frame()->height() - (is_contextual ? 1 : 2); 9701 int expected_height = frame()->height() - (is_contextual ? 1 : 2);
9680 #endif 9702 #endif
9681 9703
9682 Result result; 9704 Result result;
9683 if (is_contextual || scope()->is_global_scope() || loop_nesting() == 0) { 9705 if (is_contextual || scope()->is_global_scope() || loop_nesting() == 0) {
9684 result = frame()->CallStoreIC(name, is_contextual); 9706 result = frame()->CallStoreIC(name, is_contextual, strict_mode_flag());
9685 // A test eax instruction following the call signals that the inobject 9707 // A test eax instruction following the call signals that the inobject
9686 // property case was inlined. Ensure that there is not a test eax 9708 // property case was inlined. Ensure that there is not a test eax
9687 // instruction here. 9709 // instruction here.
9688 __ nop(); 9710 __ nop();
9689 } else { 9711 } else {
9690 // Inline the in-object property case. 9712 // Inline the in-object property case.
9691 JumpTarget slow, done; 9713 JumpTarget slow, done;
9692 Label patch_site; 9714 Label patch_site;
9693 9715
9694 // Get the value and receiver from the stack. 9716 // Get the value and receiver from the stack.
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
9758 } 9780 }
9759 __ bind(&skip_write_barrier); 9781 __ bind(&skip_write_barrier);
9760 value.Unuse(); 9782 value.Unuse();
9761 scratch.Unuse(); 9783 scratch.Unuse();
9762 receiver.Unuse(); 9784 receiver.Unuse();
9763 done.Jump(&result); 9785 done.Jump(&result);
9764 9786
9765 slow.Bind(&value, &receiver); 9787 slow.Bind(&value, &receiver);
9766 frame()->Push(&receiver); 9788 frame()->Push(&receiver);
9767 frame()->Push(&value); 9789 frame()->Push(&value);
9768 result = frame()->CallStoreIC(name, is_contextual); 9790 result = frame()->CallStoreIC(name, is_contextual, strict_mode_flag());
9769 // Encode the offset to the map check instruction and the offset 9791 // Encode the offset to the map check instruction and the offset
9770 // to the write barrier store address computation in a test eax 9792 // to the write barrier store address computation in a test eax
9771 // instruction. 9793 // instruction.
9772 int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(&patch_site); 9794 int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(&patch_site);
9773 __ test(eax, 9795 __ test(eax,
9774 Immediate((delta_to_record_write << 16) | delta_to_patch_site)); 9796 Immediate((delta_to_record_write << 16) | delta_to_patch_site));
9775 done.Bind(&result); 9797 done.Bind(&result);
9776 } 9798 }
9777 9799
9778 ASSERT_EQ(expected_height, frame()->height()); 9800 ASSERT_EQ(expected_height, frame()->height());
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
9896 9918
9897 // Make sure that value, key and receiver are in registers. 9919 // Make sure that value, key and receiver are in registers.
9898 result.ToRegister(); 9920 result.ToRegister();
9899 key.ToRegister(); 9921 key.ToRegister();
9900 receiver.ToRegister(); 9922 receiver.ToRegister();
9901 9923
9902 DeferredReferenceSetKeyedValue* deferred = 9924 DeferredReferenceSetKeyedValue* deferred =
9903 new DeferredReferenceSetKeyedValue(result.reg(), 9925 new DeferredReferenceSetKeyedValue(result.reg(),
9904 key.reg(), 9926 key.reg(),
9905 receiver.reg(), 9927 receiver.reg(),
9906 tmp.reg()); 9928 tmp.reg(),
9929 strict_mode_flag());
9907 9930
9908 // Check that the receiver is not a smi. 9931 // Check that the receiver is not a smi.
9909 __ test(receiver.reg(), Immediate(kSmiTagMask)); 9932 __ test(receiver.reg(), Immediate(kSmiTagMask));
9910 deferred->Branch(zero); 9933 deferred->Branch(zero);
9911 9934
9912 // Check that the key is a smi. 9935 // Check that the key is a smi.
9913 if (!key.is_smi()) { 9936 if (!key.is_smi()) {
9914 __ test(key.reg(), Immediate(kSmiTagMask)); 9937 __ test(key.reg(), Immediate(kSmiTagMask));
9915 deferred->Branch(not_zero); 9938 deferred->Branch(not_zero);
9916 } else { 9939 } else {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
9951 __ cmp(FieldOperand(tmp.reg(), HeapObject::kMapOffset), 9974 __ cmp(FieldOperand(tmp.reg(), HeapObject::kMapOffset),
9952 Immediate(FACTORY->fixed_array_map())); 9975 Immediate(FACTORY->fixed_array_map()));
9953 deferred->Branch(not_equal); 9976 deferred->Branch(not_equal);
9954 9977
9955 // Store the value. 9978 // Store the value.
9956 __ mov(FixedArrayElementOperand(tmp.reg(), key.reg()), result.reg()); 9979 __ mov(FixedArrayElementOperand(tmp.reg(), key.reg()), result.reg());
9957 __ IncrementCounter(COUNTERS->keyed_store_inline(), 1); 9980 __ IncrementCounter(COUNTERS->keyed_store_inline(), 1);
9958 9981
9959 deferred->BindExit(); 9982 deferred->BindExit();
9960 } else { 9983 } else {
9961 result = frame()->CallKeyedStoreIC(); 9984 result = frame()->CallKeyedStoreIC(strict_mode_flag());
9962 // Make sure that we do not have a test instruction after the 9985 // Make sure that we do not have a test instruction after the
9963 // call. A test instruction after the call is used to 9986 // call. A test instruction after the call is used to
9964 // indicate that we have generated an inline version of the 9987 // indicate that we have generated an inline version of the
9965 // keyed store. 9988 // keyed store.
9966 __ nop(); 9989 __ nop();
9967 } 9990 }
9968 ASSERT(frame()->height() == original_height - 3); 9991 ASSERT(frame()->height() == original_height - 3);
9969 return result; 9992 return result;
9970 } 9993 }
9971 9994
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
10331 memcpy(chunk->GetStartAddress(), desc.buffer, desc.instr_size); 10354 memcpy(chunk->GetStartAddress(), desc.buffer, desc.instr_size);
10332 CPU::FlushICache(chunk->GetStartAddress(), desc.instr_size); 10355 CPU::FlushICache(chunk->GetStartAddress(), desc.instr_size);
10333 return FUNCTION_CAST<MemCopyFunction>(chunk->GetStartAddress()); 10356 return FUNCTION_CAST<MemCopyFunction>(chunk->GetStartAddress());
10334 } 10357 }
10335 10358
10336 #undef __ 10359 #undef __
10337 10360
10338 } } // namespace v8::internal 10361 } } // namespace v8::internal
10339 10362
10340 #endif // V8_TARGET_ARCH_IA32 10363 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« 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