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 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 } | 144 } |
145 | 145 |
146 | 146 |
147 TypeInfoCodeGenState::~TypeInfoCodeGenState() { | 147 TypeInfoCodeGenState::~TypeInfoCodeGenState() { |
148 owner()->set_type_info(slot_, old_type_info_); | 148 owner()->set_type_info(slot_, old_type_info_); |
149 } | 149 } |
150 | 150 |
151 // ------------------------------------------------------------------------- | 151 // ------------------------------------------------------------------------- |
152 // CodeGenerator implementation | 152 // CodeGenerator implementation |
153 | 153 |
| 154 int CodeGenerator::inlined_write_barrier_size_ = -1; |
| 155 |
154 CodeGenerator::CodeGenerator(MacroAssembler* masm) | 156 CodeGenerator::CodeGenerator(MacroAssembler* masm) |
155 : deferred_(8), | 157 : deferred_(8), |
156 masm_(masm), | 158 masm_(masm), |
157 info_(NULL), | 159 info_(NULL), |
158 frame_(NULL), | 160 frame_(NULL), |
159 allocator_(NULL), | 161 allocator_(NULL), |
160 cc_reg_(al), | 162 cc_reg_(al), |
161 state_(NULL), | 163 state_(NULL), |
162 loop_nesting_(0), | 164 loop_nesting_(0), |
163 type_info_(NULL), | 165 type_info_(NULL), |
(...skipping 6054 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6218 | 6220 |
6219 virtual void Generate(); | 6221 virtual void Generate(); |
6220 | 6222 |
6221 private: | 6223 private: |
6222 Register value_; | 6224 Register value_; |
6223 Register receiver_; | 6225 Register receiver_; |
6224 Handle<String> name_; | 6226 Handle<String> name_; |
6225 }; | 6227 }; |
6226 | 6228 |
6227 | 6229 |
| 6230 // Takes value in r0, receiver in r1 and returns the result (the |
| 6231 // value) in r0. |
6228 void DeferredReferenceSetNamedValue::Generate() { | 6232 void DeferredReferenceSetNamedValue::Generate() { |
| 6233 // Record the entry frame and spill. |
| 6234 VirtualFrame copied_frame(*frame_state()->frame()); |
| 6235 copied_frame.SpillAll(); |
| 6236 |
6229 // Ensure value in r0, receiver in r1 to match store ic calling | 6237 // Ensure value in r0, receiver in r1 to match store ic calling |
6230 // convention. | 6238 // convention. |
6231 ASSERT(value_.is(r0) && receiver_.is(r1)); | 6239 ASSERT(value_.is(r0) && receiver_.is(r1)); |
6232 __ mov(r2, Operand(name_)); | 6240 __ mov(r2, Operand(name_)); |
6233 | 6241 |
6234 // The rest of the instructions in the deferred code must be together. | 6242 // The rest of the instructions in the deferred code must be together. |
6235 { Assembler::BlockConstPoolScope block_const_pool(masm_); | 6243 { Assembler::BlockConstPoolScope block_const_pool(masm_); |
6236 // Call keyed store IC. It has the arguments value, key and receiver in r0, | 6244 // Call keyed store IC. It has the arguments value, key and receiver in r0, |
6237 // r1 and r2. | 6245 // r1 and r2. |
6238 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 6246 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
6239 __ Call(ic, RelocInfo::CODE_TARGET); | 6247 __ Call(ic, RelocInfo::CODE_TARGET); |
6240 // The call must be followed by a nop instruction to indicate that the | 6248 // The call must be followed by a nop instruction to indicate that the |
6241 // named store has been inlined. | 6249 // named store has been inlined. |
6242 __ nop(PROPERTY_ACCESS_INLINED); | 6250 __ nop(PROPERTY_ACCESS_INLINED); |
6243 | 6251 |
| 6252 // Go back to the frame we entered with. The instructions |
| 6253 // generated by this merge are skipped over by the inline store |
| 6254 // patching mechanism when looking for the branch instruction that |
| 6255 // tells it where the code to patch is. |
| 6256 copied_frame.MergeTo(frame_state()->frame()); |
| 6257 |
6244 // Block the constant pool for one more instruction after leaving this | 6258 // Block the constant pool for one more instruction after leaving this |
6245 // constant pool block scope to include the branch instruction ending the | 6259 // constant pool block scope to include the branch instruction ending the |
6246 // deferred code. | 6260 // deferred code. |
6247 __ BlockConstPoolFor(1); | 6261 __ BlockConstPoolFor(1); |
6248 } | 6262 } |
6249 } | 6263 } |
6250 | 6264 |
6251 | 6265 |
6252 // Consumes the top of stack (the receiver) and pushes the result instead. | 6266 // Consumes the top of stack (the receiver) and pushes the result instead. |
6253 void CodeGenerator::EmitNamedLoad(Handle<String> name, bool is_contextual) { | 6267 void CodeGenerator::EmitNamedLoad(Handle<String> name, bool is_contextual) { |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6358 Label check_inlined_codesize; | 6372 Label check_inlined_codesize; |
6359 masm_->bind(&check_inlined_codesize); | 6373 masm_->bind(&check_inlined_codesize); |
6360 #endif | 6374 #endif |
6361 __ mov(scratch0, Operand(Factory::null_value())); | 6375 __ mov(scratch0, Operand(Factory::null_value())); |
6362 __ cmp(scratch0, scratch1); | 6376 __ cmp(scratch0, scratch1); |
6363 deferred->Branch(ne); | 6377 deferred->Branch(ne); |
6364 | 6378 |
6365 int offset = 0; | 6379 int offset = 0; |
6366 __ str(value, MemOperand(receiver, offset)); | 6380 __ str(value, MemOperand(receiver, offset)); |
6367 | 6381 |
6368 // Update the write barrier. | 6382 // Update the write barrier and record its size. We do not use |
6369 __ RecordWrite(receiver, Operand(offset), scratch0, scratch1); | 6383 // the RecordWrite macro here because we want the offset |
| 6384 // addition instruction first to make it easy to patch. |
| 6385 Label record_write_start, record_write_done; |
| 6386 __ bind(&record_write_start); |
| 6387 // Add offset into the object. |
| 6388 __ add(scratch0, receiver, Operand(offset)); |
| 6389 // Test that the object is not in the new space. We cannot set |
| 6390 // region marks for new space pages. |
| 6391 __ InNewSpace(receiver, scratch1, eq, &record_write_done); |
| 6392 // Record the actual write. |
| 6393 __ RecordWriteHelper(receiver, scratch0, scratch1); |
| 6394 __ bind(&record_write_done); |
| 6395 // Clobber all input registers when running with the debug-code flag |
| 6396 // turned on to provoke errors. |
| 6397 if (FLAG_debug_code) { |
| 6398 __ mov(receiver, Operand(BitCast<int32_t>(kZapValue))); |
| 6399 __ mov(scratch0, Operand(BitCast<int32_t>(kZapValue))); |
| 6400 __ mov(scratch1, Operand(BitCast<int32_t>(kZapValue))); |
| 6401 } |
| 6402 // Check that this is the first inlined write barrier or that |
| 6403 // this inlined write barrier has the same size as all the other |
| 6404 // inlined write barriers. |
| 6405 ASSERT((inlined_write_barrier_size_ == -1) || |
| 6406 (inlined_write_barrier_size_ == |
| 6407 masm()->InstructionsGeneratedSince(&record_write_start))); |
| 6408 inlined_write_barrier_size_ = |
| 6409 masm()->InstructionsGeneratedSince(&record_write_start); |
| 6410 |
6370 // Make sure that the expected number of instructions are generated. | 6411 // Make sure that the expected number of instructions are generated. |
6371 ASSERT_EQ(GetInlinedNamedStoreInstructionsAfterPatch(), | 6412 ASSERT_EQ(GetInlinedNamedStoreInstructionsAfterPatch(), |
6372 masm_->InstructionsGeneratedSince(&check_inlined_codesize)); | 6413 masm()->InstructionsGeneratedSince(&check_inlined_codesize)); |
6373 } | 6414 } |
6374 deferred->BindExit(); | 6415 deferred->BindExit(); |
6375 } | 6416 } |
6376 ASSERT_EQ(expected_height, frame()->height()); | 6417 ASSERT_EQ(expected_height, frame()->height()); |
6377 } | 6418 } |
6378 | 6419 |
6379 | 6420 |
6380 void CodeGenerator::EmitKeyedLoad() { | 6421 void CodeGenerator::EmitKeyedLoad() { |
6381 if (loop_nesting() == 0) { | 6422 if (loop_nesting() == 0) { |
6382 Comment cmnt(masm_, "[ Load from keyed property"); | 6423 Comment cmnt(masm_, "[ Load from keyed property"); |
(...skipping 4965 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11348 __ bind(&string_add_runtime); | 11389 __ bind(&string_add_runtime); |
11349 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); | 11390 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); |
11350 } | 11391 } |
11351 | 11392 |
11352 | 11393 |
11353 #undef __ | 11394 #undef __ |
11354 | 11395 |
11355 } } // namespace v8::internal | 11396 } } // namespace v8::internal |
11356 | 11397 |
11357 #endif // V8_TARGET_ARCH_ARM | 11398 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |