| 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 1920 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1931   } | 1931   } | 
| 1932   node->break_target()->Unuse(); | 1932   node->break_target()->Unuse(); | 
| 1933   ASSERT(!has_valid_frame() || frame_->height() == original_height); | 1933   ASSERT(!has_valid_frame() || frame_->height() == original_height); | 
| 1934 } | 1934 } | 
| 1935 | 1935 | 
| 1936 | 1936 | 
| 1937 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 1937 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 
| 1938   frame_->EmitPush(cp); | 1938   frame_->EmitPush(cp); | 
| 1939   frame_->EmitPush(Operand(pairs)); | 1939   frame_->EmitPush(Operand(pairs)); | 
| 1940   frame_->EmitPush(Operand(Smi::FromInt(is_eval() ? 1 : 0))); | 1940   frame_->EmitPush(Operand(Smi::FromInt(is_eval() ? 1 : 0))); | 
|  | 1941   frame_->EmitPush(Operand(Smi::FromInt(strict_mode_flag()))); | 
| 1941 | 1942 | 
| 1942   frame_->CallRuntime(Runtime::kDeclareGlobals, 3); | 1943   frame_->CallRuntime(Runtime::kDeclareGlobals, 4); | 
| 1943   // The result is discarded. | 1944   // The result is discarded. | 
| 1944 } | 1945 } | 
| 1945 | 1946 | 
| 1946 | 1947 | 
| 1947 void CodeGenerator::VisitDeclaration(Declaration* node) { | 1948 void CodeGenerator::VisitDeclaration(Declaration* node) { | 
| 1948 #ifdef DEBUG | 1949 #ifdef DEBUG | 
| 1949   int original_height = frame_->height(); | 1950   int original_height = frame_->height(); | 
| 1950 #endif | 1951 #endif | 
| 1951   Comment cmnt(masm_, "[ Declaration"); | 1952   Comment cmnt(masm_, "[ Declaration"); | 
| 1952   Variable* var = node->proxy()->var(); | 1953   Variable* var = node->proxy()->var(); | 
| (...skipping 1327 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3280       // context slot declaration, but we cannot initialize it at the | 3281       // context slot declaration, but we cannot initialize it at the | 
| 3281       // same time, because the const declaration may be at the end of | 3282       // same time, because the const declaration may be at the end of | 
| 3282       // the eval code (sigh...) and the const variable may have been | 3283       // the eval code (sigh...) and the const variable may have been | 
| 3283       // used before (where its value is 'undefined'). Thus, we can only | 3284       // used before (where its value is 'undefined'). Thus, we can only | 
| 3284       // do the initialization when we actually encounter the expression | 3285       // do the initialization when we actually encounter the expression | 
| 3285       // and when the expression operands are defined and valid, and | 3286       // and when the expression operands are defined and valid, and | 
| 3286       // thus we need the split into 2 operations: declaration of the | 3287       // thus we need the split into 2 operations: declaration of the | 
| 3287       // context slot followed by initialization. | 3288       // context slot followed by initialization. | 
| 3288       frame_->CallRuntime(Runtime::kInitializeConstContextSlot, 3); | 3289       frame_->CallRuntime(Runtime::kInitializeConstContextSlot, 3); | 
| 3289     } else { | 3290     } else { | 
| 3290       frame_->CallRuntime(Runtime::kStoreContextSlot, 3); | 3291       frame_->EmitPush(Operand(Smi::FromInt(strict_mode_flag()))); | 
|  | 3292       frame_->CallRuntime(Runtime::kStoreContextSlot, 4); | 
| 3291     } | 3293     } | 
| 3292     // Storing a variable must keep the (new) value on the expression | 3294     // Storing a variable must keep the (new) value on the expression | 
| 3293     // stack. This is necessary for compiling assignment expressions. | 3295     // stack. This is necessary for compiling assignment expressions. | 
| 3294     frame_->EmitPush(r0); | 3296     frame_->EmitPush(r0); | 
| 3295 | 3297 | 
| 3296   } else { | 3298   } else { | 
| 3297     ASSERT(!slot->var()->is_dynamic()); | 3299     ASSERT(!slot->var()->is_dynamic()); | 
| 3298     Register scratch = VirtualFrame::scratch0(); | 3300     Register scratch = VirtualFrame::scratch0(); | 
| 3299     Register scratch2 = VirtualFrame::scratch1(); | 3301     Register scratch2 = VirtualFrame::scratch1(); | 
| 3300 | 3302 | 
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3630             frame_->Drop(); | 3632             frame_->Drop(); | 
| 3631           } | 3633           } | 
| 3632           break; | 3634           break; | 
| 3633         } | 3635         } | 
| 3634         // else fall through | 3636         // else fall through | 
| 3635       case ObjectLiteral::Property::PROTOTYPE: { | 3637       case ObjectLiteral::Property::PROTOTYPE: { | 
| 3636         frame_->Dup(); | 3638         frame_->Dup(); | 
| 3637         Load(key); | 3639         Load(key); | 
| 3638         Load(value); | 3640         Load(value); | 
| 3639         if (property->emit_store()) { | 3641         if (property->emit_store()) { | 
| 3640           frame_->CallRuntime(Runtime::kSetProperty, 3); | 3642           frame_->EmitPush(Operand(Smi::FromInt(NONE)));  // PropertyAttributes | 
|  | 3643           frame_->CallRuntime(Runtime::kSetProperty, 4); | 
| 3641         } else { | 3644         } else { | 
| 3642           frame_->Drop(3); | 3645           frame_->Drop(3); | 
| 3643         } | 3646         } | 
| 3644         break; | 3647         break; | 
| 3645       } | 3648       } | 
| 3646       case ObjectLiteral::Property::SETTER: { | 3649       case ObjectLiteral::Property::SETTER: { | 
| 3647         frame_->Dup(); | 3650         frame_->Dup(); | 
| 3648         Load(key); | 3651         Load(key); | 
| 3649         frame_->EmitPush(Operand(Smi::FromInt(1))); | 3652         frame_->EmitPush(Operand(Smi::FromInt(1))); | 
| 3650         Load(value); | 3653         Load(value); | 
| (...skipping 3016 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 6667     // deferred code. | 6670     // deferred code. | 
| 6668     __ BlockConstPoolFor(1); | 6671     __ BlockConstPoolFor(1); | 
| 6669   } | 6672   } | 
| 6670 } | 6673 } | 
| 6671 | 6674 | 
| 6672 | 6675 | 
| 6673 class DeferredReferenceSetKeyedValue: public DeferredCode { | 6676 class DeferredReferenceSetKeyedValue: public DeferredCode { | 
| 6674  public: | 6677  public: | 
| 6675   DeferredReferenceSetKeyedValue(Register value, | 6678   DeferredReferenceSetKeyedValue(Register value, | 
| 6676                                  Register key, | 6679                                  Register key, | 
| 6677                                  Register receiver) | 6680                                  Register receiver, | 
| 6678       : value_(value), key_(key), receiver_(receiver) { | 6681                                  StrictModeFlag strict_mode) | 
|  | 6682       : value_(value), | 
|  | 6683         key_(key), | 
|  | 6684         receiver_(receiver), | 
|  | 6685         strict_mode_(strict_mode) { | 
| 6679     set_comment("[ DeferredReferenceSetKeyedValue"); | 6686     set_comment("[ DeferredReferenceSetKeyedValue"); | 
| 6680   } | 6687   } | 
| 6681 | 6688 | 
| 6682   virtual void Generate(); | 6689   virtual void Generate(); | 
| 6683 | 6690 | 
| 6684  private: | 6691  private: | 
| 6685   Register value_; | 6692   Register value_; | 
| 6686   Register key_; | 6693   Register key_; | 
| 6687   Register receiver_; | 6694   Register receiver_; | 
|  | 6695   StrictModeFlag strict_mode_; | 
| 6688 }; | 6696 }; | 
| 6689 | 6697 | 
| 6690 | 6698 | 
| 6691 void DeferredReferenceSetKeyedValue::Generate() { | 6699 void DeferredReferenceSetKeyedValue::Generate() { | 
| 6692   Register scratch1 = VirtualFrame::scratch0(); | 6700   Register scratch1 = VirtualFrame::scratch0(); | 
| 6693   Register scratch2 = VirtualFrame::scratch1(); | 6701   Register scratch2 = VirtualFrame::scratch1(); | 
| 6694   __ DecrementCounter(&Counters::keyed_store_inline, 1, scratch1, scratch2); | 6702   __ DecrementCounter(&Counters::keyed_store_inline, 1, scratch1, scratch2); | 
| 6695   __ IncrementCounter( | 6703   __ IncrementCounter( | 
| 6696       &Counters::keyed_store_inline_miss, 1, scratch1, scratch2); | 6704       &Counters::keyed_store_inline_miss, 1, scratch1, scratch2); | 
| 6697 | 6705 | 
| 6698   // Ensure value in r0, key in r1 and receiver in r2 to match keyed store ic | 6706   // Ensure value in r0, key in r1 and receiver in r2 to match keyed store ic | 
| 6699   // calling convention. | 6707   // calling convention. | 
| 6700   if (value_.is(r1)) { | 6708   if (value_.is(r1)) { | 
| 6701     __ Swap(r0, r1, ip); | 6709     __ Swap(r0, r1, ip); | 
| 6702   } | 6710   } | 
| 6703   ASSERT(receiver_.is(r2)); | 6711   ASSERT(receiver_.is(r2)); | 
| 6704 | 6712 | 
| 6705   // The rest of the instructions in the deferred code must be together. | 6713   // The rest of the instructions in the deferred code must be together. | 
| 6706   { Assembler::BlockConstPoolScope block_const_pool(masm_); | 6714   { Assembler::BlockConstPoolScope block_const_pool(masm_); | 
| 6707     // Call keyed store IC. It has the arguments value, key and receiver in r0, | 6715     // Call keyed store IC. It has the arguments value, key and receiver in r0, | 
| 6708     // r1 and r2. | 6716     // r1 and r2. | 
| 6709     Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 6717     Handle<Code> ic(Builtins::builtin( | 
|  | 6718         (strict_mode_ == kStrictMode) ? Builtins::KeyedStoreIC_Initialize_Strict | 
|  | 6719                                       : Builtins::KeyedStoreIC_Initialize)); | 
| 6710     __ Call(ic, RelocInfo::CODE_TARGET); | 6720     __ Call(ic, RelocInfo::CODE_TARGET); | 
| 6711     // The call must be followed by a nop instruction to indicate that the | 6721     // The call must be followed by a nop instruction to indicate that the | 
| 6712     // keyed store has been inlined. | 6722     // keyed store has been inlined. | 
| 6713     __ MarkCode(MacroAssembler::PROPERTY_ACCESS_INLINED); | 6723     __ MarkCode(MacroAssembler::PROPERTY_ACCESS_INLINED); | 
| 6714 | 6724 | 
| 6715     // Block the constant pool for one more instruction after leaving this | 6725     // Block the constant pool for one more instruction after leaving this | 
| 6716     // constant pool block scope to include the branch instruction ending the | 6726     // constant pool block scope to include the branch instruction ending the | 
| 6717     // deferred code. | 6727     // deferred code. | 
| 6718     __ BlockConstPoolFor(1); | 6728     __ BlockConstPoolFor(1); | 
| 6719   } | 6729   } | 
| 6720 } | 6730 } | 
| 6721 | 6731 | 
| 6722 | 6732 | 
| 6723 class DeferredReferenceSetNamedValue: public DeferredCode { | 6733 class DeferredReferenceSetNamedValue: public DeferredCode { | 
| 6724  public: | 6734  public: | 
| 6725   DeferredReferenceSetNamedValue(Register value, | 6735   DeferredReferenceSetNamedValue(Register value, | 
| 6726                                  Register receiver, | 6736                                  Register receiver, | 
| 6727                                  Handle<String> name) | 6737                                  Handle<String> name, | 
| 6728       : value_(value), receiver_(receiver), name_(name) { | 6738                                  StrictModeFlag strict_mode) | 
|  | 6739       : value_(value), | 
|  | 6740         receiver_(receiver), | 
|  | 6741         name_(name), | 
|  | 6742         strict_mode_(strict_mode) { | 
| 6729     set_comment("[ DeferredReferenceSetNamedValue"); | 6743     set_comment("[ DeferredReferenceSetNamedValue"); | 
| 6730   } | 6744   } | 
| 6731 | 6745 | 
| 6732   virtual void Generate(); | 6746   virtual void Generate(); | 
| 6733 | 6747 | 
| 6734  private: | 6748  private: | 
| 6735   Register value_; | 6749   Register value_; | 
| 6736   Register receiver_; | 6750   Register receiver_; | 
| 6737   Handle<String> name_; | 6751   Handle<String> name_; | 
|  | 6752   StrictModeFlag strict_mode_; | 
| 6738 }; | 6753 }; | 
| 6739 | 6754 | 
| 6740 | 6755 | 
| 6741 // Takes value in r0, receiver in r1 and returns the result (the | 6756 // Takes value in r0, receiver in r1 and returns the result (the | 
| 6742 // value) in r0. | 6757 // value) in r0. | 
| 6743 void DeferredReferenceSetNamedValue::Generate() { | 6758 void DeferredReferenceSetNamedValue::Generate() { | 
| 6744   // Record the entry frame and spill. | 6759   // Record the entry frame and spill. | 
| 6745   VirtualFrame copied_frame(*frame_state()->frame()); | 6760   VirtualFrame copied_frame(*frame_state()->frame()); | 
| 6746   copied_frame.SpillAll(); | 6761   copied_frame.SpillAll(); | 
| 6747 | 6762 | 
| 6748   // Ensure value in r0, receiver in r1 to match store ic calling | 6763   // Ensure value in r0, receiver in r1 to match store ic calling | 
| 6749   // convention. | 6764   // convention. | 
| 6750   ASSERT(value_.is(r0) && receiver_.is(r1)); | 6765   ASSERT(value_.is(r0) && receiver_.is(r1)); | 
| 6751   __ mov(r2, Operand(name_)); | 6766   __ mov(r2, Operand(name_)); | 
| 6752 | 6767 | 
| 6753   // The rest of the instructions in the deferred code must be together. | 6768   // The rest of the instructions in the deferred code must be together. | 
| 6754   { Assembler::BlockConstPoolScope block_const_pool(masm_); | 6769   { Assembler::BlockConstPoolScope block_const_pool(masm_); | 
| 6755     // Call keyed store IC. It has the arguments value, key and receiver in r0, | 6770     // Call keyed store IC. It has the arguments value, key and receiver in r0, | 
| 6756     // r1 and r2. | 6771     // r1 and r2. | 
| 6757     Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 6772     Handle<Code> ic(Builtins::builtin( | 
|  | 6773         (strict_mode_ == kStrictMode) ? Builtins::StoreIC_Initialize_Strict | 
|  | 6774                                       : Builtins::StoreIC_Initialize)); | 
| 6758     __ Call(ic, RelocInfo::CODE_TARGET); | 6775     __ Call(ic, RelocInfo::CODE_TARGET); | 
| 6759     // The call must be followed by a nop instruction to indicate that the | 6776     // The call must be followed by a nop instruction to indicate that the | 
| 6760     // named store has been inlined. | 6777     // named store has been inlined. | 
| 6761     __ MarkCode(MacroAssembler::PROPERTY_ACCESS_INLINED); | 6778     __ MarkCode(MacroAssembler::PROPERTY_ACCESS_INLINED); | 
| 6762 | 6779 | 
| 6763     // Go back to the frame we entered with. The instructions | 6780     // Go back to the frame we entered with. The instructions | 
| 6764     // generated by this merge are skipped over by the inline store | 6781     // generated by this merge are skipped over by the inline store | 
| 6765     // patching mechanism when looking for the branch instruction that | 6782     // patching mechanism when looking for the branch instruction that | 
| 6766     // tells it where the code to patch is. | 6783     // tells it where the code to patch is. | 
| 6767     copied_frame.MergeTo(frame_state()->frame()); | 6784     copied_frame.MergeTo(frame_state()->frame()); | 
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 6936     // Inline the in-object property case. | 6953     // Inline the in-object property case. | 
| 6937     JumpTarget slow, done; | 6954     JumpTarget slow, done; | 
| 6938 | 6955 | 
| 6939     // Get the value and receiver from the stack. | 6956     // Get the value and receiver from the stack. | 
| 6940     frame()->PopToR0(); | 6957     frame()->PopToR0(); | 
| 6941     Register value = r0; | 6958     Register value = r0; | 
| 6942     frame()->PopToR1(); | 6959     frame()->PopToR1(); | 
| 6943     Register receiver = r1; | 6960     Register receiver = r1; | 
| 6944 | 6961 | 
| 6945     DeferredReferenceSetNamedValue* deferred = | 6962     DeferredReferenceSetNamedValue* deferred = | 
| 6946         new DeferredReferenceSetNamedValue(value, receiver, name); | 6963         new DeferredReferenceSetNamedValue( | 
|  | 6964           value, receiver, name, strict_mode_flag()); | 
| 6947 | 6965 | 
| 6948     // Check that the receiver is a heap object. | 6966     // Check that the receiver is a heap object. | 
| 6949     __ tst(receiver, Operand(kSmiTagMask)); | 6967     __ tst(receiver, Operand(kSmiTagMask)); | 
| 6950     deferred->Branch(eq); | 6968     deferred->Branch(eq); | 
| 6951 | 6969 | 
| 6952     // The following instructions are the part of the inlined | 6970     // The following instructions are the part of the inlined | 
| 6953     // in-object property store code which can be patched. Therefore | 6971     // in-object property store code which can be patched. Therefore | 
| 6954     // the exact number of instructions generated must be fixed, so | 6972     // the exact number of instructions generated must be fixed, so | 
| 6955     // the constant pool is blocked while generating this code. | 6973     // the constant pool is blocked while generating this code. | 
| 6956     { Assembler::BlockConstPoolScope block_const_pool(masm_); | 6974     { Assembler::BlockConstPoolScope block_const_pool(masm_); | 
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 7122     VirtualFrame::SpilledScope spilled(frame_); | 7140     VirtualFrame::SpilledScope spilled(frame_); | 
| 7123     Register receiver = r2; | 7141     Register receiver = r2; | 
| 7124     frame_->EmitPop(receiver); | 7142     frame_->EmitPop(receiver); | 
| 7125 | 7143 | 
| 7126 #ifdef DEBUG | 7144 #ifdef DEBUG | 
| 7127     bool we_remembered_the_write_barrier = value_is_harmless; | 7145     bool we_remembered_the_write_barrier = value_is_harmless; | 
| 7128 #endif | 7146 #endif | 
| 7129 | 7147 | 
| 7130     // The deferred code expects value, key and receiver in registers. | 7148     // The deferred code expects value, key and receiver in registers. | 
| 7131     DeferredReferenceSetKeyedValue* deferred = | 7149     DeferredReferenceSetKeyedValue* deferred = | 
| 7132         new DeferredReferenceSetKeyedValue(value, key, receiver); | 7150         new DeferredReferenceSetKeyedValue( | 
|  | 7151           value, key, receiver, strict_mode_flag()); | 
| 7133 | 7152 | 
| 7134     // Check that the value is a smi. As this inlined code does not set the | 7153     // Check that the value is a smi. As this inlined code does not set the | 
| 7135     // write barrier it is only possible to store smi values. | 7154     // write barrier it is only possible to store smi values. | 
| 7136     if (!value_is_harmless) { | 7155     if (!value_is_harmless) { | 
| 7137       // If the value is not likely to be a Smi then let's test the fixed array | 7156       // If the value is not likely to be a Smi then let's test the fixed array | 
| 7138       // for new space instead.  See below. | 7157       // for new space instead.  See below. | 
| 7139       if (wb_info == LIKELY_SMI) { | 7158       if (wb_info == LIKELY_SMI) { | 
| 7140         __ tst(value, Operand(kSmiTagMask)); | 7159         __ tst(value, Operand(kSmiTagMask)); | 
| 7141         deferred->Branch(ne); | 7160         deferred->Branch(ne); | 
| 7142 #ifdef DEBUG | 7161 #ifdef DEBUG | 
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 7207 | 7226 | 
| 7208       // Make sure that the expected number of instructions are generated. | 7227       // Make sure that the expected number of instructions are generated. | 
| 7209       ASSERT_EQ(kInlinedKeyedStoreInstructionsAfterPatch, | 7228       ASSERT_EQ(kInlinedKeyedStoreInstructionsAfterPatch, | 
| 7210                 masm_->InstructionsGeneratedSince(&check_inlined_codesize)); | 7229                 masm_->InstructionsGeneratedSince(&check_inlined_codesize)); | 
| 7211     } | 7230     } | 
| 7212 | 7231 | 
| 7213     ASSERT(we_remembered_the_write_barrier); | 7232     ASSERT(we_remembered_the_write_barrier); | 
| 7214 | 7233 | 
| 7215     deferred->BindExit(); | 7234     deferred->BindExit(); | 
| 7216   } else { | 7235   } else { | 
| 7217     frame()->CallKeyedStoreIC(); | 7236     frame()->CallKeyedStoreIC(strict_mode_flag()); | 
| 7218   } | 7237   } | 
| 7219 } | 7238 } | 
| 7220 | 7239 | 
| 7221 | 7240 | 
| 7222 #ifdef DEBUG | 7241 #ifdef DEBUG | 
| 7223 bool CodeGenerator::HasValidEntryRegisters() { return true; } | 7242 bool CodeGenerator::HasValidEntryRegisters() { return true; } | 
| 7224 #endif | 7243 #endif | 
| 7225 | 7244 | 
| 7226 | 7245 | 
| 7227 #undef __ | 7246 #undef __ | 
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 7375                BinaryOpIC::GetName(runtime_operands_type_)); | 7394                BinaryOpIC::GetName(runtime_operands_type_)); | 
| 7376   return name_; | 7395   return name_; | 
| 7377 } | 7396 } | 
| 7378 | 7397 | 
| 7379 | 7398 | 
| 7380 #undef __ | 7399 #undef __ | 
| 7381 | 7400 | 
| 7382 } }  // namespace v8::internal | 7401 } }  // namespace v8::internal | 
| 7383 | 7402 | 
| 7384 #endif  // V8_TARGET_ARCH_ARM | 7403 #endif  // V8_TARGET_ARCH_ARM | 
| OLD | NEW | 
|---|