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

Side by Side Diff: src/x64/codegen-x64.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/x64/codegen-x64.h ('k') | src/x64/codegen-x64-inl.h » ('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 2011 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
11 // with the distribution. 11 // with the distribution.
(...skipping 2729 matching lines...) Expand 10 before | Expand all | Expand 10 after
2741 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 2741 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
2742 // Call the runtime to declare the globals. The inevitable call 2742 // Call the runtime to declare the globals. The inevitable call
2743 // will sync frame elements to memory anyway, so we do it eagerly to 2743 // will sync frame elements to memory anyway, so we do it eagerly to
2744 // allow us to push the arguments directly into place. 2744 // allow us to push the arguments directly into place.
2745 frame_->SyncRange(0, frame_->element_count() - 1); 2745 frame_->SyncRange(0, frame_->element_count() - 1);
2746 2746
2747 __ movq(kScratchRegister, pairs, RelocInfo::EMBEDDED_OBJECT); 2747 __ movq(kScratchRegister, pairs, RelocInfo::EMBEDDED_OBJECT);
2748 frame_->EmitPush(rsi); // The context is the first argument. 2748 frame_->EmitPush(rsi); // The context is the first argument.
2749 frame_->EmitPush(kScratchRegister); 2749 frame_->EmitPush(kScratchRegister);
2750 frame_->EmitPush(Smi::FromInt(is_eval() ? 1 : 0)); 2750 frame_->EmitPush(Smi::FromInt(is_eval() ? 1 : 0));
2751 Result ignored = frame_->CallRuntime(Runtime::kDeclareGlobals, 3); 2751 frame_->EmitPush(Smi::FromInt(strict_mode_flag()));
2752 Result ignored = frame_->CallRuntime(Runtime::kDeclareGlobals, 4);
2752 // Return value is ignored. 2753 // Return value is ignored.
2753 } 2754 }
2754 2755
2755 2756
2756 void CodeGenerator::VisitDeclaration(Declaration* node) { 2757 void CodeGenerator::VisitDeclaration(Declaration* node) {
2757 Comment cmnt(masm_, "[ Declaration"); 2758 Comment cmnt(masm_, "[ Declaration");
2758 Variable* var = node->proxy()->var(); 2759 Variable* var = node->proxy()->var();
2759 ASSERT(var != NULL); // must have been resolved 2760 ASSERT(var != NULL); // must have been resolved
2760 Slot* slot = var->AsSlot(); 2761 Slot* slot = var->AsSlot();
2761 2762
(...skipping 1837 matching lines...) Expand 10 before | Expand all | Expand 10 after
4599 // context slot declaration, but we cannot initialize it at the same 4600 // context slot declaration, but we cannot initialize it at the same
4600 // time, because the const declaration may be at the end of the eval 4601 // time, because the const declaration may be at the end of the eval
4601 // code (sigh...) and the const variable may have been used before 4602 // code (sigh...) and the const variable may have been used before
4602 // (where its value is 'undefined'). Thus, we can only do the 4603 // (where its value is 'undefined'). Thus, we can only do the
4603 // initialization when we actually encounter the expression and when 4604 // initialization when we actually encounter the expression and when
4604 // the expression operands are defined and valid, and thus we need the 4605 // the expression operands are defined and valid, and thus we need the
4605 // split into 2 operations: declaration of the context slot followed 4606 // split into 2 operations: declaration of the context slot followed
4606 // by initialization. 4607 // by initialization.
4607 value = frame_->CallRuntime(Runtime::kInitializeConstContextSlot, 3); 4608 value = frame_->CallRuntime(Runtime::kInitializeConstContextSlot, 3);
4608 } else { 4609 } else {
4609 value = frame_->CallRuntime(Runtime::kStoreContextSlot, 3); 4610 frame_->Push(Smi::FromInt(strict_mode_flag()));
4611 value = frame_->CallRuntime(Runtime::kStoreContextSlot, 4);
4610 } 4612 }
4611 // Storing a variable must keep the (new) value on the expression 4613 // Storing a variable must keep the (new) value on the expression
4612 // stack. This is necessary for compiling chained assignment 4614 // stack. This is necessary for compiling chained assignment
4613 // expressions. 4615 // expressions.
4614 frame_->Push(&value); 4616 frame_->Push(&value);
4615 } else { 4617 } else {
4616 ASSERT(!slot->var()->is_dynamic()); 4618 ASSERT(!slot->var()->is_dynamic());
4617 4619
4618 JumpTarget exit; 4620 JumpTarget exit;
4619 if (init_state == CONST_INIT) { 4621 if (init_state == CONST_INIT) {
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
4888 if (CompileTimeValue::IsCompileTimeValue(property->value())) break; 4890 if (CompileTimeValue::IsCompileTimeValue(property->value())) break;
4889 // else fall through. 4891 // else fall through.
4890 case ObjectLiteral::Property::COMPUTED: { 4892 case ObjectLiteral::Property::COMPUTED: {
4891 Handle<Object> key(property->key()->handle()); 4893 Handle<Object> key(property->key()->handle());
4892 if (key->IsSymbol()) { 4894 if (key->IsSymbol()) {
4893 // Duplicate the object as the IC receiver. 4895 // Duplicate the object as the IC receiver.
4894 frame_->Dup(); 4896 frame_->Dup();
4895 Load(property->value()); 4897 Load(property->value());
4896 if (property->emit_store()) { 4898 if (property->emit_store()) {
4897 Result ignored = 4899 Result ignored =
4898 frame_->CallStoreIC(Handle<String>::cast(key), false); 4900 frame_->CallStoreIC(Handle<String>::cast(key), false,
4901 strict_mode_flag());
4899 // A test rax instruction following the store IC call would 4902 // A test rax instruction following the store IC call would
4900 // indicate the presence of an inlined version of the 4903 // indicate the presence of an inlined version of the
4901 // store. Add a nop to indicate that there is no such 4904 // store. Add a nop to indicate that there is no such
4902 // inlined version. 4905 // inlined version.
4903 __ nop(); 4906 __ nop();
4904 } else { 4907 } else {
4905 frame_->Drop(2); 4908 frame_->Drop(2);
4906 } 4909 }
4907 break; 4910 break;
4908 } 4911 }
4909 // Fall through 4912 // Fall through
4910 } 4913 }
4911 case ObjectLiteral::Property::PROTOTYPE: { 4914 case ObjectLiteral::Property::PROTOTYPE: {
4912 // Duplicate the object as an argument to the runtime call. 4915 // Duplicate the object as an argument to the runtime call.
4913 frame_->Dup(); 4916 frame_->Dup();
4914 Load(property->key()); 4917 Load(property->key());
4915 Load(property->value()); 4918 Load(property->value());
4916 if (property->emit_store()) { 4919 if (property->emit_store()) {
4920 frame_->Push(Smi::FromInt(NONE)); // PropertyAttributes
4917 // Ignore the result. 4921 // Ignore the result.
4918 Result ignored = frame_->CallRuntime(Runtime::kSetProperty, 3); 4922 Result ignored = frame_->CallRuntime(Runtime::kSetProperty, 4);
4919 } else { 4923 } else {
4920 frame_->Drop(3); 4924 frame_->Drop(3);
4921 } 4925 }
4922 break; 4926 break;
4923 } 4927 }
4924 case ObjectLiteral::Property::SETTER: { 4928 case ObjectLiteral::Property::SETTER: {
4925 // Duplicate the object as an argument to the runtime call. 4929 // Duplicate the object as an argument to the runtime call.
4926 frame_->Dup(); 4930 frame_->Dup();
4927 Load(property->key()); 4931 Load(property->key());
4928 frame_->Push(Smi::FromInt(1)); 4932 frame_->Push(Smi::FromInt(1));
(...skipping 2094 matching lines...) Expand 10 before | Expand all | Expand 10 after
7023 answer = frame()->CallRuntime(Runtime::kMath_pow_cfunction, 2); 7027 answer = frame()->CallRuntime(Runtime::kMath_pow_cfunction, 2);
7024 7028
7025 done.Bind(&answer); 7029 done.Bind(&answer);
7026 frame()->Push(&answer); 7030 frame()->Push(&answer);
7027 } 7031 }
7028 7032
7029 7033
7030 void CodeGenerator::GenerateMathSin(ZoneList<Expression*>* args) { 7034 void CodeGenerator::GenerateMathSin(ZoneList<Expression*>* args) {
7031 ASSERT_EQ(args->length(), 1); 7035 ASSERT_EQ(args->length(), 1);
7032 Load(args->at(0)); 7036 Load(args->at(0));
7033 TranscendentalCacheStub stub(TranscendentalCache::SIN); 7037 TranscendentalCacheStub stub(TranscendentalCache::SIN,
7038 TranscendentalCacheStub::TAGGED);
7034 Result result = frame_->CallStub(&stub, 1); 7039 Result result = frame_->CallStub(&stub, 1);
7035 frame_->Push(&result); 7040 frame_->Push(&result);
7036 } 7041 }
7037 7042
7038 7043
7039 void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) { 7044 void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) {
7040 ASSERT_EQ(args->length(), 1); 7045 ASSERT_EQ(args->length(), 1);
7041 Load(args->at(0)); 7046 Load(args->at(0));
7042 TranscendentalCacheStub stub(TranscendentalCache::COS); 7047 TranscendentalCacheStub stub(TranscendentalCache::COS,
7048 TranscendentalCacheStub::TAGGED);
7043 Result result = frame_->CallStub(&stub, 1); 7049 Result result = frame_->CallStub(&stub, 1);
7044 frame_->Push(&result); 7050 frame_->Push(&result);
7045 } 7051 }
7046 7052
7047 7053
7048 void CodeGenerator::GenerateMathLog(ZoneList<Expression*>* args) { 7054 void CodeGenerator::GenerateMathLog(ZoneList<Expression*>* args) {
7049 ASSERT_EQ(args->length(), 1); 7055 ASSERT_EQ(args->length(), 1);
7050 Load(args->at(0)); 7056 Load(args->at(0));
7051 TranscendentalCacheStub stub(TranscendentalCache::LOG); 7057 TranscendentalCacheStub stub(TranscendentalCache::LOG,
7058 TranscendentalCacheStub::TAGGED);
7052 Result result = frame_->CallStub(&stub, 1); 7059 Result result = frame_->CallStub(&stub, 1);
7053 frame_->Push(&result); 7060 frame_->Push(&result);
7054 } 7061 }
7055 7062
7056 7063
7057 // Generates the Math.sqrt method. Please note - this function assumes that 7064 // Generates the Math.sqrt method. Please note - this function assumes that
7058 // the callsite has executed ToNumber on the argument. 7065 // the callsite has executed ToNumber on the argument.
7059 void CodeGenerator::GenerateMathSqrt(ZoneList<Expression*>* args) { 7066 void CodeGenerator::GenerateMathSqrt(ZoneList<Expression*>* args) {
7060 ASSERT(args->length() == 1); 7067 ASSERT(args->length() == 1);
7061 Load(args->at(0)); 7068 Load(args->at(0));
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
7223 destination()->Invert(); 7230 destination()->Invert();
7224 LoadCondition(node->expression(), destination(), true); 7231 LoadCondition(node->expression(), destination(), true);
7225 // Swap the labels back. 7232 // Swap the labels back.
7226 destination()->Invert(); 7233 destination()->Invert();
7227 7234
7228 } else if (op == Token::DELETE) { 7235 } else if (op == Token::DELETE) {
7229 Property* property = node->expression()->AsProperty(); 7236 Property* property = node->expression()->AsProperty();
7230 if (property != NULL) { 7237 if (property != NULL) {
7231 Load(property->obj()); 7238 Load(property->obj());
7232 Load(property->key()); 7239 Load(property->key());
7233 Result answer = frame_->InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, 2); 7240 frame_->Push(Smi::FromInt(strict_mode_flag()));
7241 Result answer = frame_->InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, 3);
7234 frame_->Push(&answer); 7242 frame_->Push(&answer);
7235 return; 7243 return;
7236 } 7244 }
7237 7245
7238 Variable* variable = node->expression()->AsVariableProxy()->AsVariable(); 7246 Variable* variable = node->expression()->AsVariableProxy()->AsVariable();
7239 if (variable != NULL) { 7247 if (variable != NULL) {
7248 // Delete of an unqualified identifier is disallowed in strict mode
7249 // but "delete this" is.
7250 ASSERT(strict_mode_flag() == kNonStrictMode || variable->is_this());
7240 Slot* slot = variable->AsSlot(); 7251 Slot* slot = variable->AsSlot();
7241 if (variable->is_global()) { 7252 if (variable->is_global()) {
7242 LoadGlobal(); 7253 LoadGlobal();
7243 frame_->Push(variable->name()); 7254 frame_->Push(variable->name());
7255 frame_->Push(Smi::FromInt(kNonStrictMode));
7244 Result answer = frame_->InvokeBuiltin(Builtins::DELETE, 7256 Result answer = frame_->InvokeBuiltin(Builtins::DELETE,
7245 CALL_FUNCTION, 2); 7257 CALL_FUNCTION, 3);
7246 frame_->Push(&answer); 7258 frame_->Push(&answer);
7247 return;
7248 7259
7249 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { 7260 } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
7250 // Call the runtime to delete from the context holding the named 7261 // Call the runtime to delete from the context holding the named
7251 // variable. Sync the virtual frame eagerly so we can push the 7262 // variable. Sync the virtual frame eagerly so we can push the
7252 // arguments directly into place. 7263 // arguments directly into place.
7253 frame_->SyncRange(0, frame_->element_count() - 1); 7264 frame_->SyncRange(0, frame_->element_count() - 1);
7254 frame_->EmitPush(rsi); 7265 frame_->EmitPush(rsi);
7255 frame_->EmitPush(variable->name()); 7266 frame_->EmitPush(variable->name());
7256 Result answer = frame_->CallRuntime(Runtime::kDeleteContextSlot, 2); 7267 Result answer = frame_->CallRuntime(Runtime::kDeleteContextSlot, 2);
7257 frame_->Push(&answer); 7268 frame_->Push(&answer);
7258 return; 7269 } else {
7270 // Default: Result of deleting non-global, not dynamically
7271 // introduced variables is false.
7272 frame_->Push(FACTORY->false_value());
7259 } 7273 }
7260
7261 // Default: Result of deleting non-global, not dynamically
7262 // introduced variables is false.
7263 frame_->Push(FACTORY->false_value());
7264
7265 } else { 7274 } else {
7266 // Default: Result of deleting expressions is true. 7275 // Default: Result of deleting expressions is true.
7267 Load(node->expression()); // may have side-effects 7276 Load(node->expression()); // may have side-effects
7268 frame_->SetElementAt(0, FACTORY->true_value()); 7277 frame_->SetElementAt(0, FACTORY->true_value());
7269 } 7278 }
7270 7279
7271 } else if (op == Token::TYPEOF) { 7280 } else if (op == Token::TYPEOF) {
7272 // Special case for loading the typeof expression; see comment on 7281 // Special case for loading the typeof expression; see comment on
7273 // LoadTypeofExpression(). 7282 // LoadTypeofExpression().
7274 LoadTypeofExpression(node->expression()); 7283 LoadTypeofExpression(node->expression());
(...skipping 790 matching lines...) Expand 10 before | Expand all | Expand 10 after
8065 __ IncrementCounter(COUNTERS->keyed_load_inline_miss(), 1); 8074 __ IncrementCounter(COUNTERS->keyed_load_inline_miss(), 1);
8066 8075
8067 if (!dst_.is(rax)) __ movq(dst_, rax); 8076 if (!dst_.is(rax)) __ movq(dst_, rax);
8068 } 8077 }
8069 8078
8070 8079
8071 class DeferredReferenceSetKeyedValue: public DeferredCode { 8080 class DeferredReferenceSetKeyedValue: public DeferredCode {
8072 public: 8081 public:
8073 DeferredReferenceSetKeyedValue(Register value, 8082 DeferredReferenceSetKeyedValue(Register value,
8074 Register key, 8083 Register key,
8075 Register receiver) 8084 Register receiver,
8076 : value_(value), key_(key), receiver_(receiver) { 8085 StrictModeFlag strict_mode)
8086 : value_(value),
8087 key_(key),
8088 receiver_(receiver),
8089 strict_mode_(strict_mode) {
8077 set_comment("[ DeferredReferenceSetKeyedValue"); 8090 set_comment("[ DeferredReferenceSetKeyedValue");
8078 } 8091 }
8079 8092
8080 virtual void Generate(); 8093 virtual void Generate();
8081 8094
8082 Label* patch_site() { return &patch_site_; } 8095 Label* patch_site() { return &patch_site_; }
8083 8096
8084 private: 8097 private:
8085 Register value_; 8098 Register value_;
8086 Register key_; 8099 Register key_;
8087 Register receiver_; 8100 Register receiver_;
8088 Label patch_site_; 8101 Label patch_site_;
8102 StrictModeFlag strict_mode_;
8089 }; 8103 };
8090 8104
8091 8105
8092 void DeferredReferenceSetKeyedValue::Generate() { 8106 void DeferredReferenceSetKeyedValue::Generate() {
8093 __ IncrementCounter(COUNTERS->keyed_store_inline_miss(), 1); 8107 __ IncrementCounter(COUNTERS->keyed_store_inline_miss(), 1);
8094 // Move value, receiver, and key to registers rax, rdx, and rcx, as 8108 // Move value, receiver, and key to registers rax, rdx, and rcx, as
8095 // the IC stub expects. 8109 // the IC stub expects.
8096 // Move value to rax, using xchg if the receiver or key is in rax. 8110 // Move value to rax, using xchg if the receiver or key is in rax.
8097 if (!value_.is(rax)) { 8111 if (!value_.is(rax)) {
8098 if (!receiver_.is(rax) && !key_.is(rax)) { 8112 if (!receiver_.is(rax) && !key_.is(rax)) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
8131 } 8145 }
8132 } else if (key_.is(rcx)) { 8146 } else if (key_.is(rcx)) {
8133 __ movq(rdx, receiver_); 8147 __ movq(rdx, receiver_);
8134 } else { 8148 } else {
8135 __ movq(rcx, key_); 8149 __ movq(rcx, key_);
8136 __ movq(rdx, receiver_); 8150 __ movq(rdx, receiver_);
8137 } 8151 }
8138 8152
8139 // Call the IC stub. 8153 // Call the IC stub.
8140 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 8154 Handle<Code> ic(Isolate::Current()->builtins()->builtin(
8141 Builtins::KeyedStoreIC_Initialize)); 8155 (strict_mode_ == kStrictMode) ? Builtins::KeyedStoreIC_Initialize_Strict
8156 : Builtins::KeyedStoreIC_Initialize));
8142 __ Call(ic, RelocInfo::CODE_TARGET); 8157 __ Call(ic, RelocInfo::CODE_TARGET);
8143 // The delta from the start of the map-compare instructions (initial movq) 8158 // The delta from the start of the map-compare instructions (initial movq)
8144 // to the test instruction. We use masm_-> directly here instead of the 8159 // to the test instruction. We use masm_-> directly here instead of the
8145 // __ macro because the macro sometimes uses macro expansion to turn 8160 // __ macro because the macro sometimes uses macro expansion to turn
8146 // into something that can't return a value. This is encountered 8161 // into something that can't return a value. This is encountered
8147 // when doing generated code coverage tests. 8162 // when doing generated code coverage tests.
8148 int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(patch_site()); 8163 int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(patch_site());
8149 // Here we use masm_-> instead of the __ macro because this is the 8164 // Here we use masm_-> instead of the __ macro because this is the
8150 // instruction that gets patched and coverage code gets in the way. 8165 // instruction that gets patched and coverage code gets in the way.
8151 masm_->testl(rax, Immediate(-delta_to_patch_site)); 8166 masm_->testl(rax, Immediate(-delta_to_patch_site));
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
8231 } 8246 }
8232 8247
8233 8248
8234 Result CodeGenerator::EmitNamedStore(Handle<String> name, bool is_contextual) { 8249 Result CodeGenerator::EmitNamedStore(Handle<String> name, bool is_contextual) {
8235 #ifdef DEBUG 8250 #ifdef DEBUG
8236 int expected_height = frame()->height() - (is_contextual ? 1 : 2); 8251 int expected_height = frame()->height() - (is_contextual ? 1 : 2);
8237 #endif 8252 #endif
8238 8253
8239 Result result; 8254 Result result;
8240 if (is_contextual || scope()->is_global_scope() || loop_nesting() == 0) { 8255 if (is_contextual || scope()->is_global_scope() || loop_nesting() == 0) {
8241 result = frame()->CallStoreIC(name, is_contextual); 8256 result = frame()->CallStoreIC(name, is_contextual, strict_mode_flag());
8242 // A test rax instruction following the call signals that the inobject 8257 // A test rax instruction following the call signals that the inobject
8243 // property case was inlined. Ensure that there is not a test rax 8258 // property case was inlined. Ensure that there is not a test rax
8244 // instruction here. 8259 // instruction here.
8245 __ nop(); 8260 __ nop();
8246 } else { 8261 } else {
8247 // Inline the in-object property case. 8262 // Inline the in-object property case.
8248 JumpTarget slow, done; 8263 JumpTarget slow, done;
8249 Label patch_site; 8264 Label patch_site;
8250 8265
8251 // Get the value and receiver from the stack. 8266 // Get the value and receiver from the stack.
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
8331 } 8346 }
8332 __ bind(&skip_write_barrier); 8347 __ bind(&skip_write_barrier);
8333 value.Unuse(); 8348 value.Unuse();
8334 scratch.Unuse(); 8349 scratch.Unuse();
8335 receiver.Unuse(); 8350 receiver.Unuse();
8336 done.Jump(&result); 8351 done.Jump(&result);
8337 8352
8338 slow.Bind(&value, &receiver); 8353 slow.Bind(&value, &receiver);
8339 frame()->Push(&receiver); 8354 frame()->Push(&receiver);
8340 frame()->Push(&value); 8355 frame()->Push(&value);
8341 result = frame()->CallStoreIC(name, is_contextual); 8356 result = frame()->CallStoreIC(name, is_contextual, strict_mode_flag());
8342 // Encode the offset to the map check instruction and the offset 8357 // Encode the offset to the map check instruction and the offset
8343 // to the write barrier store address computation in a test rax 8358 // to the write barrier store address computation in a test rax
8344 // instruction. 8359 // instruction.
8345 int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(&patch_site); 8360 int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(&patch_site);
8346 __ testl(rax, 8361 __ testl(rax,
8347 Immediate((delta_to_record_write << 16) | delta_to_patch_site)); 8362 Immediate((delta_to_record_write << 16) | delta_to_patch_site));
8348 done.Bind(&result); 8363 done.Bind(&result);
8349 } 8364 }
8350 8365
8351 ASSERT_EQ(expected_height, frame()->height()); 8366 ASSERT_EQ(expected_height, frame()->height());
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
8472 bool value_is_constant = result.is_constant(); 8487 bool value_is_constant = result.is_constant();
8473 8488
8474 // Make sure that value, key and receiver are in registers. 8489 // Make sure that value, key and receiver are in registers.
8475 result.ToRegister(); 8490 result.ToRegister();
8476 key.ToRegister(); 8491 key.ToRegister();
8477 receiver.ToRegister(); 8492 receiver.ToRegister();
8478 8493
8479 DeferredReferenceSetKeyedValue* deferred = 8494 DeferredReferenceSetKeyedValue* deferred =
8480 new DeferredReferenceSetKeyedValue(result.reg(), 8495 new DeferredReferenceSetKeyedValue(result.reg(),
8481 key.reg(), 8496 key.reg(),
8482 receiver.reg()); 8497 receiver.reg(),
8498 strict_mode_flag());
8483 8499
8484 // Check that the receiver is not a smi. 8500 // Check that the receiver is not a smi.
8485 __ JumpIfSmi(receiver.reg(), deferred->entry_label()); 8501 __ JumpIfSmi(receiver.reg(), deferred->entry_label());
8486 8502
8487 // Check that the key is a smi. 8503 // Check that the key is a smi.
8488 if (!key.is_smi()) { 8504 if (!key.is_smi()) {
8489 __ JumpIfNotSmi(key.reg(), deferred->entry_label()); 8505 __ JumpIfNotSmi(key.reg(), deferred->entry_label());
8490 } else if (FLAG_debug_code) { 8506 } else if (FLAG_debug_code) {
8491 __ AbortIfNotSmi(key.reg()); 8507 __ AbortIfNotSmi(key.reg());
8492 } 8508 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
8534 masm()->SmiToIndex(kScratchRegister, key.reg(), kPointerSizeLog2); 8550 masm()->SmiToIndex(kScratchRegister, key.reg(), kPointerSizeLog2);
8535 __ movq(FieldOperand(tmp.reg(), 8551 __ movq(FieldOperand(tmp.reg(),
8536 index.reg, 8552 index.reg,
8537 index.scale, 8553 index.scale,
8538 FixedArray::kHeaderSize), 8554 FixedArray::kHeaderSize),
8539 result.reg()); 8555 result.reg());
8540 __ IncrementCounter(COUNTERS->keyed_store_inline(), 1); 8556 __ IncrementCounter(COUNTERS->keyed_store_inline(), 1);
8541 8557
8542 deferred->BindExit(); 8558 deferred->BindExit();
8543 } else { 8559 } else {
8544 result = frame()->CallKeyedStoreIC(); 8560 result = frame()->CallKeyedStoreIC(strict_mode_flag());
8545 // Make sure that we do not have a test instruction after the 8561 // Make sure that we do not have a test instruction after the
8546 // call. A test instruction after the call is used to 8562 // call. A test instruction after the call is used to
8547 // indicate that we have generated an inline version of the 8563 // indicate that we have generated an inline version of the
8548 // keyed store. 8564 // keyed store.
8549 __ nop(); 8565 __ nop();
8550 } 8566 }
8551 ASSERT(frame()->height() == original_height - 3); 8567 ASSERT(frame()->height() == original_height - 3);
8552 return result; 8568 return result;
8553 } 8569 }
8554 8570
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
8813 } 8829 }
8814 8830
8815 #endif 8831 #endif
8816 8832
8817 8833
8818 #undef __ 8834 #undef __
8819 8835
8820 } } // namespace v8::internal 8836 } } // namespace v8::internal
8821 8837
8822 #endif // V8_TARGET_ARCH_X64 8838 #endif // V8_TARGET_ARCH_X64
OLDNEW
« 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