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

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

Issue 2878043: Port inlined in-object property stores to ARM. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 5 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
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 6189 matching lines...) Expand 10 before | Expand all | Expand 10 after
6200 __ nop(PROPERTY_ACCESS_INLINED); 6200 __ nop(PROPERTY_ACCESS_INLINED);
6201 6201
6202 // Block the constant pool for one more instruction after leaving this 6202 // Block the constant pool for one more instruction after leaving this
6203 // constant pool block scope to include the branch instruction ending the 6203 // constant pool block scope to include the branch instruction ending the
6204 // deferred code. 6204 // deferred code.
6205 __ BlockConstPoolFor(1); 6205 __ BlockConstPoolFor(1);
6206 } 6206 }
6207 } 6207 }
6208 6208
6209 6209
6210 class DeferredReferenceSetNamedValue: public DeferredCode {
6211 public:
6212 DeferredReferenceSetNamedValue(Register value,
6213 Register receiver,
6214 Handle<String> name)
6215 : value_(value), receiver_(receiver), name_(name) {
6216 set_comment("[ DeferredReferenceSetNamedValue");
6217 }
6218
6219 virtual void Generate();
6220
6221 private:
6222 Register value_;
6223 Register receiver_;
6224 Handle<String> name_;
6225 };
6226
6227
6228 void DeferredReferenceSetNamedValue::Generate() {
6229 // Ensure value in r0, receiver in r1 to match store ic calling
6230 // convention.
6231 ASSERT(value_.is(r0) && receiver_.is(r1));
6232 __ mov(r2, Operand(name_));
6233
6234 // The rest of the instructions in the deferred code must be together.
6235 { Assembler::BlockConstPoolScope block_const_pool(masm_);
6236 // Call keyed store IC. It has the arguments value, key and receiver in r0,
6237 // r1 and r2.
6238 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
6239 __ Call(ic, RelocInfo::CODE_TARGET);
6240 // The call must be followed by a nop instruction to indicate that the
6241 // named store has been inlined.
6242 __ nop(PROPERTY_ACCESS_INLINED);
6243
6244 // Block the constant pool for one more instruction after leaving this
6245 // constant pool block scope to include the branch instruction ending the
6246 // deferred code.
William Hesse 2010/07/22 08:11:23 It looked like some support for register allocatio
Mads Ager (chromium) 2010/07/22 08:28:53 That is a good question. This follows the pattern
6247 __ BlockConstPoolFor(1);
6248 }
6249 }
6250
6251
6210 // Consumes the top of stack (the receiver) and pushes the result instead. 6252 // Consumes the top of stack (the receiver) and pushes the result instead.
6211 void CodeGenerator::EmitNamedLoad(Handle<String> name, bool is_contextual) { 6253 void CodeGenerator::EmitNamedLoad(Handle<String> name, bool is_contextual) {
6212 if (is_contextual || scope()->is_global_scope() || loop_nesting() == 0) { 6254 if (is_contextual || scope()->is_global_scope() || loop_nesting() == 0) {
6213 Comment cmnt(masm(), "[ Load from named Property"); 6255 Comment cmnt(masm(), "[ Load from named Property");
6214 // Setup the name register and call load IC. 6256 // Setup the name register and call load IC.
6215 frame_->CallLoadIC(name, 6257 frame_->CallLoadIC(name,
6216 is_contextual 6258 is_contextual
6217 ? RelocInfo::CODE_TARGET_CONTEXT 6259 ? RelocInfo::CODE_TARGET_CONTEXT
6218 : RelocInfo::CODE_TARGET); 6260 : RelocInfo::CODE_TARGET);
6219 frame_->EmitPush(r0); // Push answer. 6261 frame_->EmitPush(r0); // Push answer.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
6270 deferred->BindExit(); 6312 deferred->BindExit();
6271 // At this point the receiver register has the result, either from the 6313 // At this point the receiver register has the result, either from the
6272 // deferred code or from the inlined code. 6314 // deferred code or from the inlined code.
6273 frame_->EmitPush(receiver); 6315 frame_->EmitPush(receiver);
6274 } 6316 }
6275 } 6317 }
6276 6318
6277 6319
6278 void CodeGenerator::EmitNamedStore(Handle<String> name, bool is_contextual) { 6320 void CodeGenerator::EmitNamedStore(Handle<String> name, bool is_contextual) {
6279 #ifdef DEBUG 6321 #ifdef DEBUG
6280 int expected_height = frame_->height() - (is_contextual ? 1 : 2); 6322 int expected_height = frame()->height() - (is_contextual ? 1 : 2);
6281 #endif 6323 #endif
6282 frame_->CallStoreIC(name, is_contextual);
6283 6324
6284 ASSERT_EQ(expected_height, frame_->height()); 6325 Result result;
6326 if (is_contextual || scope()->is_global_scope() || loop_nesting() == 0) {
6327 frame()->CallStoreIC(name, is_contextual);
6328 } else {
6329 // Inline the in-object property case.
6330 JumpTarget slow, done;
6331
6332 // Get the value and receiver from the stack.
6333 frame()->PopToR0();
6334 Register value = r0;
6335 frame()->PopToR1();
6336 Register receiver = r1;
6337
6338 DeferredReferenceSetNamedValue* deferred =
6339 new DeferredReferenceSetNamedValue(value, receiver, name);
6340
6341 // Check that the receiver is a heap object.
6342 __ tst(receiver, Operand(kSmiTagMask));
6343 deferred->Branch(eq);
6344
6345 // The following instructions are the part of the inlined
6346 // in-object property store code which can be patched. Therefore
6347 // the exact number of instructions generated must be fixed, so
6348 // the constant pool is blocked while generating this code.
6349 { Assembler::BlockConstPoolScope block_const_pool(masm_);
6350 Register scratch0 = VirtualFrame::scratch0();
6351 Register scratch1 = VirtualFrame::scratch1();
6352
6353 // Check the map. Initially use an invalid map to force a
6354 // failure. The map check will be patched in the runtime system.
6355 __ ldr(scratch1, FieldMemOperand(receiver, HeapObject::kMapOffset));
6356
6357 #ifdef DEBUG
6358 Label check_inlined_codesize;
6359 masm_->bind(&check_inlined_codesize);
6360 #endif
6361 __ mov(scratch0, Operand(Factory::null_value()));
Rodolph Perfetta 2010/07/21 14:51:15 On ARM it should probably be LoadRoot(scratch0, He
Mads Ager (chromium) 2010/07/22 07:29:54 Normally, yes. In this specific case I actually wa
6362 __ cmp(scratch0, scratch1);
6363 deferred->Branch(ne);
6364
6365 int offset = 0;
6366 __ str(value, MemOperand(receiver, offset));
6367
6368 // Update the write barrier.
6369 __ RecordWrite(receiver, Operand(offset), scratch0, scratch1);
6370 // Make sure that the expected number of instructions are generated.
6371 ASSERT_EQ(GetInlinedNamedStoreInstructionsAfterPatch(),
6372 masm_->InstructionsGeneratedSince(&check_inlined_codesize));
6373 }
6374 deferred->BindExit();
6375 }
6376 ASSERT_EQ(expected_height, frame()->height());
6285 } 6377 }
6286 6378
6287 6379
6288 void CodeGenerator::EmitKeyedLoad() { 6380 void CodeGenerator::EmitKeyedLoad() {
6289 if (loop_nesting() == 0) { 6381 if (loop_nesting() == 0) {
6290 Comment cmnt(masm_, "[ Load from keyed property"); 6382 Comment cmnt(masm_, "[ Load from keyed property");
6291 frame_->CallKeyedLoadIC(); 6383 frame_->CallKeyedLoadIC();
6292 } else { 6384 } else {
6293 // Inline the keyed load. 6385 // Inline the keyed load.
6294 Comment cmnt(masm_, "[ Inlined load from keyed property"); 6386 Comment cmnt(masm_, "[ Inlined load from keyed property");
(...skipping 4961 matching lines...) Expand 10 before | Expand all | Expand 10 after
11256 __ bind(&string_add_runtime); 11348 __ bind(&string_add_runtime);
11257 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); 11349 __ TailCallRuntime(Runtime::kStringAdd, 2, 1);
11258 } 11350 }
11259 11351
11260 11352
11261 #undef __ 11353 #undef __
11262 11354
11263 } } // namespace v8::internal 11355 } } // namespace v8::internal
11264 11356
11265 #endif // V8_TARGET_ARCH_ARM 11357 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« src/arm/assembler-arm.cc ('K') | « src/arm/codegen-arm.h ('k') | src/arm/ic-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698