| OLD | NEW | 
|      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 5147 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   5158     frame_->EmitPush(r0); |   5158     frame_->EmitPush(r0); | 
|   5159   } |   5159   } | 
|   5160   ASSERT_EQ(original_height + 1, frame_->height()); |   5160   ASSERT_EQ(original_height + 1, frame_->height()); | 
|   5161 } |   5161 } | 
|   5162  |   5162  | 
|   5163  |   5163  | 
|   5164 void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) { |   5164 void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) { | 
|   5165 #ifdef DEBUG |   5165 #ifdef DEBUG | 
|   5166   int original_height = frame_->height(); |   5166   int original_height = frame_->height(); | 
|   5167 #endif |   5167 #endif | 
|   5168   VirtualFrame::SpilledScope spilled_scope(frame_); |  | 
|   5169   Comment cmnt(masm_, "[ UnaryOperation"); |   5168   Comment cmnt(masm_, "[ UnaryOperation"); | 
|   5170  |   5169  | 
|   5171   Token::Value op = node->op(); |   5170   Token::Value op = node->op(); | 
|   5172  |   5171  | 
|   5173   if (op == Token::NOT) { |   5172   if (op == Token::NOT) { | 
|   5174     LoadCondition(node->expression(), false_target(), true_target(), true); |   5173     LoadCondition(node->expression(), false_target(), true_target(), true); | 
|   5175     // LoadCondition may (and usually does) leave a test and branch to |   5174     // LoadCondition may (and usually does) leave a test and branch to | 
|   5176     // be emitted by the caller.  In that case, negate the condition. |   5175     // be emitted by the caller.  In that case, negate the condition. | 
|   5177     if (has_cc()) cc_reg_ = NegateCondition(cc_reg_); |   5176     if (has_cc()) cc_reg_ = NegateCondition(cc_reg_); | 
|   5178  |   5177  | 
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   5230          node->expression()->AsBinaryOperation()->ResultOverwriteAllowed()); |   5229          node->expression()->AsBinaryOperation()->ResultOverwriteAllowed()); | 
|   5231     Load(node->expression()); |   5230     Load(node->expression()); | 
|   5232     switch (op) { |   5231     switch (op) { | 
|   5233       case Token::NOT: |   5232       case Token::NOT: | 
|   5234       case Token::DELETE: |   5233       case Token::DELETE: | 
|   5235       case Token::TYPEOF: |   5234       case Token::TYPEOF: | 
|   5236         UNREACHABLE();  // handled above |   5235         UNREACHABLE();  // handled above | 
|   5237         break; |   5236         break; | 
|   5238  |   5237  | 
|   5239       case Token::SUB: { |   5238       case Token::SUB: { | 
|   5240         VirtualFrame::SpilledScope spilled(frame_); |   5239         frame_->PopToR0(); | 
|   5241         frame_->EmitPop(r0); |  | 
|   5242         GenericUnaryOpStub stub(Token::SUB, overwrite); |   5240         GenericUnaryOpStub stub(Token::SUB, overwrite); | 
|   5243         frame_->CallStub(&stub, 0); |   5241         frame_->CallStub(&stub, 0); | 
|   5244         frame_->EmitPush(r0);  // r0 has result |   5242         frame_->EmitPush(r0);  // r0 has result | 
|   5245         break; |   5243         break; | 
|   5246       } |   5244       } | 
|   5247  |   5245  | 
|   5248       case Token::BIT_NOT: { |   5246       case Token::BIT_NOT: { | 
|   5249         // smi check |   5247         Register tos = frame_->PopToRegister(); | 
|   5250         VirtualFrame::SpilledScope spilled(frame_); |   5248         JumpTarget not_smi_label; | 
|   5251         frame_->EmitPop(r0); |  | 
|   5252         JumpTarget smi_label; |  | 
|   5253         JumpTarget continue_label; |   5249         JumpTarget continue_label; | 
|   5254         __ tst(r0, Operand(kSmiTagMask)); |   5250         // Smi check. | 
|   5255         smi_label.Branch(eq); |   5251         __ tst(tos, Operand(kSmiTagMask)); | 
 |   5252         not_smi_label.Branch(ne); | 
|   5256  |   5253  | 
 |   5254         __ mvn(tos, Operand(tos)); | 
 |   5255         __ bic(tos, tos, Operand(kSmiTagMask));  // Bit-clear inverted smi-tag. | 
 |   5256         frame_->EmitPush(tos); | 
 |   5257         // The fast case is the first to jump to the continue label, so it gets | 
 |   5258         // to decide the virtual frame layout. | 
 |   5259         continue_label.Jump(); | 
 |   5260  | 
 |   5261         not_smi_label.Bind(); | 
 |   5262         frame_->SpillAll(); | 
 |   5263         __ Move(r0, tos); | 
|   5257         GenericUnaryOpStub stub(Token::BIT_NOT, overwrite); |   5264         GenericUnaryOpStub stub(Token::BIT_NOT, overwrite); | 
|   5258         frame_->CallStub(&stub, 0); |   5265         frame_->CallStub(&stub, 0); | 
|   5259         continue_label.Jump(); |   5266         frame_->EmitPush(r0); | 
|   5260  |   5267  | 
|   5261         smi_label.Bind(); |  | 
|   5262         __ mvn(r0, Operand(r0)); |  | 
|   5263         __ bic(r0, r0, Operand(kSmiTagMask));  // bit-clear inverted smi-tag |  | 
|   5264         continue_label.Bind(); |   5268         continue_label.Bind(); | 
|   5265         frame_->EmitPush(r0);  // r0 has result |  | 
|   5266         break; |   5269         break; | 
|   5267       } |   5270       } | 
|   5268  |   5271  | 
|   5269       case Token::VOID: |   5272       case Token::VOID: | 
|   5270         frame_->Drop(); |   5273         frame_->Drop(); | 
|   5271         frame_->EmitPushRoot(Heap::kUndefinedValueRootIndex); |   5274         frame_->EmitPushRoot(Heap::kUndefinedValueRootIndex); | 
|   5272         break; |   5275         break; | 
|   5273  |   5276  | 
|   5274       case Token::ADD: { |   5277       case Token::ADD: { | 
|   5275         VirtualFrame::SpilledScope spilled(frame_); |   5278         Register tos = frame_->Peek(); | 
|   5276         frame_->EmitPop(r0); |  | 
|   5277         // Smi check. |   5279         // Smi check. | 
|   5278         JumpTarget continue_label; |   5280         JumpTarget continue_label; | 
|   5279         __ tst(r0, Operand(kSmiTagMask)); |   5281         __ tst(tos, Operand(kSmiTagMask)); | 
|   5280         continue_label.Branch(eq); |   5282         continue_label.Branch(eq); | 
 |   5283  | 
 |   5284         frame_->InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, 1); | 
|   5281         frame_->EmitPush(r0); |   5285         frame_->EmitPush(r0); | 
|   5282         frame_->InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, 1); |   5286  | 
|   5283         continue_label.Bind(); |   5287         continue_label.Bind(); | 
|   5284         frame_->EmitPush(r0);  // r0 has result |  | 
|   5285         break; |   5288         break; | 
|   5286       } |   5289       } | 
|   5287       default: |   5290       default: | 
|   5288         UNREACHABLE(); |   5291         UNREACHABLE(); | 
|   5289     } |   5292     } | 
|   5290   } |   5293   } | 
|   5291   ASSERT(!has_valid_frame() || |   5294   ASSERT(!has_valid_frame() || | 
|   5292          (has_cc() && frame_->height() == original_height) || |   5295          (has_cc() && frame_->height() == original_height) || | 
|   5293          (!has_cc() && frame_->height() == original_height + 1)); |   5296          (!has_cc() && frame_->height() == original_height + 1)); | 
|   5294 } |   5297 } | 
|   5295  |   5298  | 
|   5296  |   5299  | 
|   5297 void CodeGenerator::VisitCountOperation(CountOperation* node) { |   5300 void CodeGenerator::VisitCountOperation(CountOperation* node) { | 
|   5298 #ifdef DEBUG |   5301 #ifdef DEBUG | 
|   5299   int original_height = frame_->height(); |   5302   int original_height = frame_->height(); | 
|   5300 #endif |   5303 #endif | 
|   5301   Comment cmnt(masm_, "[ CountOperation"); |   5304   Comment cmnt(masm_, "[ CountOperation"); | 
 |   5305   VirtualFrame::RegisterAllocationScope scope(this); | 
|   5302  |   5306  | 
|   5303   bool is_postfix = node->is_postfix(); |   5307   bool is_postfix = node->is_postfix(); | 
|   5304   bool is_increment = node->op() == Token::INC; |   5308   bool is_increment = node->op() == Token::INC; | 
|   5305  |   5309  | 
|   5306   Variable* var = node->expression()->AsVariableProxy()->AsVariable(); |   5310   Variable* var = node->expression()->AsVariableProxy()->AsVariable(); | 
|   5307   bool is_const = (var != NULL && var->mode() == Variable::CONST); |   5311   bool is_const = (var != NULL && var->mode() == Variable::CONST); | 
|   5308   bool is_slot = (var != NULL && var->mode() == Variable::VAR); |   5312   bool is_slot = (var != NULL && var->mode() == Variable::VAR); | 
|   5309  |   5313  | 
|   5310   if (!is_const && is_slot && type_info(var->slot()).IsSmi()) { |   5314   if (!is_const && is_slot && type_info(var->slot()).IsSmi()) { | 
|   5311     // The type info declares that this variable is always a Smi.  That |   5315     // The type info declares that this variable is always a Smi.  That | 
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   5435   // operators must yield the result of one of the two expressions |   5439   // operators must yield the result of one of the two expressions | 
|   5436   // before any ToBoolean() conversions. This means that the value |   5440   // before any ToBoolean() conversions. This means that the value | 
|   5437   // produced by a && or || operator is not necessarily a boolean. |   5441   // produced by a && or || operator is not necessarily a boolean. | 
|   5438  |   5442  | 
|   5439   // NOTE: If the left hand side produces a materialized value (not in |   5443   // NOTE: If the left hand side produces a materialized value (not in | 
|   5440   // the CC register), we force the right hand side to do the |   5444   // the CC register), we force the right hand side to do the | 
|   5441   // same. This is necessary because we may have to branch to the exit |   5445   // same. This is necessary because we may have to branch to the exit | 
|   5442   // after evaluating the left hand side (due to the shortcut |   5446   // after evaluating the left hand side (due to the shortcut | 
|   5443   // semantics), but the compiler must (statically) know if the result |   5447   // semantics), but the compiler must (statically) know if the result | 
|   5444   // of compiling the binary operation is materialized or not. |   5448   // of compiling the binary operation is materialized or not. | 
|   5445   VirtualFrame::SpilledScope spilled_scope(frame_); |  | 
|   5446   if (node->op() == Token::AND) { |   5449   if (node->op() == Token::AND) { | 
|   5447     JumpTarget is_true; |   5450     JumpTarget is_true; | 
|   5448     LoadCondition(node->left(), &is_true, false_target(), false); |   5451     LoadCondition(node->left(), &is_true, false_target(), false); | 
|   5449     if (has_valid_frame() && !has_cc()) { |   5452     if (has_valid_frame() && !has_cc()) { | 
|   5450       // The left-hand side result is on top of the virtual frame. |   5453       // The left-hand side result is on top of the virtual frame. | 
|   5451       JumpTarget pop_and_continue; |   5454       JumpTarget pop_and_continue; | 
|   5452       JumpTarget exit; |   5455       JumpTarget exit; | 
|   5453  |   5456  | 
|   5454       frame_->Dup(); |   5457       frame_->Dup(); | 
|   5455       // Avoid popping the result if it converts to 'false' using the |   5458       // Avoid popping the result if it converts to 'false' using the | 
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   5620   // equality. |   5623   // equality. | 
|   5621   if (op == Token::EQ || op == Token::EQ_STRICT) { |   5624   if (op == Token::EQ || op == Token::EQ_STRICT) { | 
|   5622     bool left_is_null = |   5625     bool left_is_null = | 
|   5623         left->AsLiteral() != NULL && left->AsLiteral()->IsNull(); |   5626         left->AsLiteral() != NULL && left->AsLiteral()->IsNull(); | 
|   5624     bool right_is_null = |   5627     bool right_is_null = | 
|   5625         right->AsLiteral() != NULL && right->AsLiteral()->IsNull(); |   5628         right->AsLiteral() != NULL && right->AsLiteral()->IsNull(); | 
|   5626     // The 'null' value can only be equal to 'null' or 'undefined'. |   5629     // The 'null' value can only be equal to 'null' or 'undefined'. | 
|   5627     if (left_is_null || right_is_null) { |   5630     if (left_is_null || right_is_null) { | 
|   5628       Load(left_is_null ? right : left); |   5631       Load(left_is_null ? right : left); | 
|   5629       Register tos = frame_->PopToRegister(); |   5632       Register tos = frame_->PopToRegister(); | 
|   5630       // JumpTargets can't cope with register allocation yet. |  | 
|   5631       frame_->SpillAll(); |  | 
|   5632       __ LoadRoot(ip, Heap::kNullValueRootIndex); |   5633       __ LoadRoot(ip, Heap::kNullValueRootIndex); | 
|   5633       __ cmp(tos, ip); |   5634       __ cmp(tos, ip); | 
|   5634  |   5635  | 
|   5635       // The 'null' value is only equal to 'undefined' if using non-strict |   5636       // The 'null' value is only equal to 'undefined' if using non-strict | 
|   5636       // comparisons. |   5637       // comparisons. | 
|   5637       if (op != Token::EQ_STRICT) { |   5638       if (op != Token::EQ_STRICT) { | 
|   5638         true_target()->Branch(eq); |   5639         true_target()->Branch(eq); | 
|   5639  |   5640  | 
|   5640         __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |   5641         __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 
|   5641         __ cmp(tos, Operand(ip)); |   5642         __ cmp(tos, Operand(ip)); | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
|   5664   if ((op == Token::EQ || op == Token::EQ_STRICT) && |   5665   if ((op == Token::EQ || op == Token::EQ_STRICT) && | 
|   5665       (operation != NULL && operation->op() == Token::TYPEOF) && |   5666       (operation != NULL && operation->op() == Token::TYPEOF) && | 
|   5666       (right->AsLiteral() != NULL && |   5667       (right->AsLiteral() != NULL && | 
|   5667        right->AsLiteral()->handle()->IsString())) { |   5668        right->AsLiteral()->handle()->IsString())) { | 
|   5668     Handle<String> check(String::cast(*right->AsLiteral()->handle())); |   5669     Handle<String> check(String::cast(*right->AsLiteral()->handle())); | 
|   5669  |   5670  | 
|   5670     // Load the operand, move it to a register. |   5671     // Load the operand, move it to a register. | 
|   5671     LoadTypeofExpression(operation->expression()); |   5672     LoadTypeofExpression(operation->expression()); | 
|   5672     Register tos = frame_->PopToRegister(); |   5673     Register tos = frame_->PopToRegister(); | 
|   5673  |   5674  | 
|   5674     // JumpTargets can't cope with register allocation yet. |  | 
|   5675     frame_->SpillAll(); |  | 
|   5676  |  | 
|   5677     Register scratch = VirtualFrame::scratch0(); |   5675     Register scratch = VirtualFrame::scratch0(); | 
|   5678  |   5676  | 
|   5679     if (check->Equals(Heap::number_symbol())) { |   5677     if (check->Equals(Heap::number_symbol())) { | 
|   5680       __ tst(tos, Operand(kSmiTagMask)); |   5678       __ tst(tos, Operand(kSmiTagMask)); | 
|   5681       true_target()->Branch(eq); |   5679       true_target()->Branch(eq); | 
|   5682       __ ldr(tos, FieldMemOperand(tos, HeapObject::kMapOffset)); |   5680       __ ldr(tos, FieldMemOperand(tos, HeapObject::kMapOffset)); | 
|   5683       __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); |   5681       __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); | 
|   5684       __ cmp(tos, ip); |   5682       __ cmp(tos, ip); | 
|   5685       cc_reg_ = eq; |   5683       cc_reg_ = eq; | 
|   5686  |   5684  | 
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   5787  |   5785  | 
|   5788     case Token::GTE: |   5786     case Token::GTE: | 
|   5789       Comparison(ge, left, right); |   5787       Comparison(ge, left, right); | 
|   5790       break; |   5788       break; | 
|   5791  |   5789  | 
|   5792     case Token::EQ_STRICT: |   5790     case Token::EQ_STRICT: | 
|   5793       Comparison(eq, left, right, true); |   5791       Comparison(eq, left, right, true); | 
|   5794       break; |   5792       break; | 
|   5795  |   5793  | 
|   5796     case Token::IN: { |   5794     case Token::IN: { | 
|   5797       VirtualFrame::SpilledScope scope(frame_); |  | 
|   5798       Load(left); |   5795       Load(left); | 
|   5799       Load(right); |   5796       Load(right); | 
|   5800       frame_->InvokeBuiltin(Builtins::IN, CALL_JS, 2); |   5797       frame_->InvokeBuiltin(Builtins::IN, CALL_JS, 2); | 
|   5801       frame_->EmitPush(r0); |   5798       frame_->EmitPush(r0); | 
|   5802       break; |   5799       break; | 
|   5803     } |   5800     } | 
|   5804  |   5801  | 
|   5805     case Token::INSTANCEOF: { |   5802     case Token::INSTANCEOF: { | 
|   5806       VirtualFrame::SpilledScope scope(frame_); |  | 
|   5807       Load(left); |   5803       Load(left); | 
|   5808       Load(right); |   5804       Load(right); | 
|   5809       InstanceofStub stub; |   5805       InstanceofStub stub; | 
|   5810       frame_->CallStub(&stub, 2); |   5806       frame_->CallStub(&stub, 2); | 
|   5811       // At this point if instanceof succeeded then r0 == 0. |   5807       // At this point if instanceof succeeded then r0 == 0. | 
|   5812       __ tst(r0, Operand(r0)); |   5808       __ tst(r0, Operand(r0)); | 
|   5813       cc_reg_ = eq; |   5809       cc_reg_ = eq; | 
|   5814       break; |   5810       break; | 
|   5815     } |   5811     } | 
|   5816  |   5812  | 
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   5894   } |   5890   } | 
|   5895  |   5891  | 
|   5896   virtual void Generate(); |   5892   virtual void Generate(); | 
|   5897  |   5893  | 
|   5898  private: |   5894  private: | 
|   5899   Register key_; |   5895   Register key_; | 
|   5900   Register receiver_; |   5896   Register receiver_; | 
|   5901 }; |   5897 }; | 
|   5902  |   5898  | 
|   5903  |   5899  | 
 |   5900 // Takes key and register in r0 and r1 or vice versa.  Returns result | 
 |   5901 // in r0. | 
|   5904 void DeferredReferenceGetKeyedValue::Generate() { |   5902 void DeferredReferenceGetKeyedValue::Generate() { | 
|   5905   ASSERT((key_.is(r0) && receiver_.is(r1)) || |   5903   ASSERT((key_.is(r0) && receiver_.is(r1)) || | 
|   5906          (key_.is(r1) && receiver_.is(r0))); |   5904          (key_.is(r1) && receiver_.is(r0))); | 
|   5907  |   5905  | 
 |   5906   VirtualFrame copied_frame(*frame_state()->frame()); | 
 |   5907   copied_frame.SpillAll(); | 
 |   5908  | 
|   5908   Register scratch1 = VirtualFrame::scratch0(); |   5909   Register scratch1 = VirtualFrame::scratch0(); | 
|   5909   Register scratch2 = VirtualFrame::scratch1(); |   5910   Register scratch2 = VirtualFrame::scratch1(); | 
|   5910   __ DecrementCounter(&Counters::keyed_load_inline, 1, scratch1, scratch2); |   5911   __ DecrementCounter(&Counters::keyed_load_inline, 1, scratch1, scratch2); | 
|   5911   __ IncrementCounter(&Counters::keyed_load_inline_miss, 1, scratch1, scratch2); |   5912   __ IncrementCounter(&Counters::keyed_load_inline_miss, 1, scratch1, scratch2); | 
|   5912  |   5913  | 
|   5913   // Ensure key in r0 and receiver in r1 to match keyed load ic calling |   5914   // Ensure key in r0 and receiver in r1 to match keyed load ic calling | 
|   5914   // convention. |   5915   // convention. | 
|   5915   if (key_.is(r1)) { |   5916   if (key_.is(r1)) { | 
|   5916     __ Swap(r0, r1, ip); |   5917     __ Swap(r0, r1, ip); | 
|   5917   } |   5918   } | 
|   5918  |   5919  | 
|   5919   // The rest of the instructions in the deferred code must be together. |   5920   // The rest of the instructions in the deferred code must be together. | 
|   5920   { Assembler::BlockConstPoolScope block_const_pool(masm_); |   5921   { Assembler::BlockConstPoolScope block_const_pool(masm_); | 
|   5921     // Call keyed load IC. It has the arguments key and receiver in r0 and r1. |   5922     // Call keyed load IC. It has the arguments key and receiver in r0 and r1. | 
|   5922     Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |   5923     Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 
|   5923     __ Call(ic, RelocInfo::CODE_TARGET); |   5924     __ Call(ic, RelocInfo::CODE_TARGET); | 
|   5924     // The call must be followed by a nop instruction to indicate that the |   5925     // The call must be followed by a nop instruction to indicate that the | 
|   5925     // keyed load has been inlined. |   5926     // keyed load has been inlined. | 
|   5926     __ nop(PROPERTY_ACCESS_INLINED); |   5927     __ nop(PROPERTY_ACCESS_INLINED); | 
|   5927  |   5928  | 
 |   5929     // Now go back to the frame that we entered with.  This will not overwrite | 
 |   5930     // the receiver or key registers since they were not in use when we came | 
 |   5931     // in.  The instructions emitted by this merge are skipped over by the | 
 |   5932     // inline load patching mechanism when looking for the branch instruction | 
 |   5933     // that tells it where the code to patch is. | 
 |   5934     copied_frame.MergeTo(frame_state()->frame()); | 
 |   5935  | 
|   5928     // Block the constant pool for one more instruction after leaving this |   5936     // Block the constant pool for one more instruction after leaving this | 
|   5929     // constant pool block scope to include the branch instruction ending the |   5937     // constant pool block scope to include the branch instruction ending the | 
|   5930     // deferred code. |   5938     // deferred code. | 
|   5931     __ BlockConstPoolFor(1); |   5939     __ BlockConstPoolFor(1); | 
|   5932   } |   5940   } | 
|   5933 } |   5941 } | 
|   5934  |   5942  | 
|   5935  |   5943  | 
|   5936 class DeferredReferenceSetKeyedValue: public DeferredCode { |   5944 class DeferredReferenceSetKeyedValue: public DeferredCode { | 
|   5937  public: |   5945  public: | 
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   6071  |   6079  | 
|   6072     // Counter will be decremented in the deferred code. Placed here to avoid |   6080     // Counter will be decremented in the deferred code. Placed here to avoid | 
|   6073     // having it in the instruction stream below where patching will occur. |   6081     // having it in the instruction stream below where patching will occur. | 
|   6074     __ IncrementCounter(&Counters::keyed_load_inline, 1, |   6082     __ IncrementCounter(&Counters::keyed_load_inline, 1, | 
|   6075                         frame_->scratch0(), frame_->scratch1()); |   6083                         frame_->scratch0(), frame_->scratch1()); | 
|   6076  |   6084  | 
|   6077     // Load the key and receiver from the stack. |   6085     // Load the key and receiver from the stack. | 
|   6078     bool key_is_known_smi = frame_->KnownSmiAt(0); |   6086     bool key_is_known_smi = frame_->KnownSmiAt(0); | 
|   6079     Register key = frame_->PopToRegister(); |   6087     Register key = frame_->PopToRegister(); | 
|   6080     Register receiver = frame_->PopToRegister(key); |   6088     Register receiver = frame_->PopToRegister(key); | 
|   6081     VirtualFrame::SpilledScope spilled(frame_); |  | 
|   6082  |   6089  | 
|   6083     // The deferred code expects key and receiver in registers. |   6090     // The deferred code expects key and receiver in registers. | 
|   6084     DeferredReferenceGetKeyedValue* deferred = |   6091     DeferredReferenceGetKeyedValue* deferred = | 
|   6085         new DeferredReferenceGetKeyedValue(key, receiver); |   6092         new DeferredReferenceGetKeyedValue(key, receiver); | 
|   6086  |   6093  | 
|   6087     // Check that the receiver is a heap object. |   6094     // Check that the receiver is a heap object. | 
|   6088     __ tst(receiver, Operand(kSmiTagMask)); |   6095     __ tst(receiver, Operand(kSmiTagMask)); | 
|   6089     deferred->Branch(eq); |   6096     deferred->Branch(eq); | 
|   6090  |   6097  | 
|   6091     // The following instructions are the part of the inlined load keyed |   6098     // The following instructions are the part of the inlined load keyed | 
| (...skipping 4604 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  10696   __ bind(&string_add_runtime); |  10703   __ bind(&string_add_runtime); | 
|  10697   __ TailCallRuntime(Runtime::kStringAdd, 2, 1); |  10704   __ TailCallRuntime(Runtime::kStringAdd, 2, 1); | 
|  10698 } |  10705 } | 
|  10699  |  10706  | 
|  10700  |  10707  | 
|  10701 #undef __ |  10708 #undef __ | 
|  10702  |  10709  | 
|  10703 } }  // namespace v8::internal |  10710 } }  // namespace v8::internal | 
|  10704  |  10711  | 
|  10705 #endif  // V8_TARGET_ARCH_ARM |  10712 #endif  // V8_TARGET_ARCH_ARM | 
| OLD | NEW |