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

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

Issue 660095: Merge revision 3813 to 3930 from bleeding_edge to partial snapshots branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/partial_snapshots/
Patch Set: '' Created 10 years, 10 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/arm/full-codegen-arm.cc ('k') | src/arm/macro-assembler-arm.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 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 // 52 //
53 // t0 - used to hold the property dictionary. 53 // t0 - used to hold the property dictionary.
54 // 54 //
55 // t1 - initially the receiver 55 // t1 - initially the receiver
56 // - used for the index into the property dictionary 56 // - used for the index into the property dictionary
57 // - holds the result on exit. 57 // - holds the result on exit.
58 // 58 //
59 // r3 - used as temporary and to hold the capacity of the property 59 // r3 - used as temporary and to hold the capacity of the property
60 // dictionary. 60 // dictionary.
61 // 61 //
62 // r2 - holds the name of the property and is unchanges. 62 // r2 - holds the name of the property and is unchanged.
63 63
64 Label done; 64 Label done;
65 65
66 // Check for the absence of an interceptor. 66 // Check for the absence of an interceptor.
67 // Load the map into t0. 67 // Load the map into t0.
68 __ ldr(t0, FieldMemOperand(t1, JSObject::kMapOffset)); 68 __ ldr(t0, FieldMemOperand(t1, JSObject::kMapOffset));
69 // Test the has_named_interceptor bit in the map. 69 // Test the has_named_interceptor bit in the map.
70 __ ldr(r3, FieldMemOperand(t0, Map::kInstanceAttributesOffset)); 70 __ ldr(r3, FieldMemOperand(t0, Map::kInstanceAttributesOffset));
71 __ tst(r3, Operand(1 << (Map::kHasNamedInterceptor + (3 * 8)))); 71 __ tst(r3, Operand(1 << (Map::kHasNamedInterceptor + (3 * 8))));
72 // Jump to miss if the interceptor bit is set. 72 // Jump to miss if the interceptor bit is set.
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 void LoadIC::GenerateStringLength(MacroAssembler* masm) { 164 void LoadIC::GenerateStringLength(MacroAssembler* masm) {
165 // ----------- S t a t e ------------- 165 // ----------- S t a t e -------------
166 // -- r2 : name 166 // -- r2 : name
167 // -- lr : return address 167 // -- lr : return address
168 // -- [sp] : receiver 168 // -- [sp] : receiver
169 // ----------------------------------- 169 // -----------------------------------
170 Label miss; 170 Label miss;
171 171
172 __ ldr(r0, MemOperand(sp, 0)); 172 __ ldr(r0, MemOperand(sp, 0));
173 173
174 StubCompiler::GenerateLoadStringLength2(masm, r0, r1, r3, &miss); 174 StubCompiler::GenerateLoadStringLength(masm, r0, r1, r3, &miss);
175 // Cache miss: Jump to runtime. 175 // Cache miss: Jump to runtime.
176 __ bind(&miss); 176 __ bind(&miss);
177 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC); 177 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
178 } 178 }
179 179
180 180
181 void LoadIC::GenerateFunctionPrototype(MacroAssembler* masm) { 181 void LoadIC::GenerateFunctionPrototype(MacroAssembler* masm) {
182 // ----------- S t a t e ------------- 182 // ----------- S t a t e -------------
183 // -- r2 : name 183 // -- r2 : name
184 // -- lr : return address 184 // -- lr : return address
185 // -- [sp] : receiver 185 // -- [sp] : receiver
186 // ----------------------------------- 186 // -----------------------------------
187 Label miss; 187 Label miss;
188 188
189 // Load receiver. 189 // Load receiver.
190 __ ldr(r0, MemOperand(sp, 0)); 190 __ ldr(r0, MemOperand(sp, 0));
191 191
192 StubCompiler::GenerateLoadFunctionPrototype(masm, r0, r1, r3, &miss); 192 StubCompiler::GenerateLoadFunctionPrototype(masm, r0, r1, r3, &miss);
193 __ bind(&miss); 193 __ bind(&miss);
194 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC); 194 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
195 } 195 }
196 196
197 197
198 // Defined in ic.cc. 198 // Defined in ic.cc.
199 Object* CallIC_Miss(Arguments args); 199 Object* CallIC_Miss(Arguments args);
200 200
201 void CallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) { 201 void CallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) {
202 // ----------- S t a t e ------------- 202 // ----------- S t a t e -------------
203 // -- lr: return address 203 // -- r2 : name
204 // -- lr : return address
204 // ----------------------------------- 205 // -----------------------------------
205 Label number, non_number, non_string, boolean, probe, miss; 206 Label number, non_number, non_string, boolean, probe, miss;
206 207
207 // Get the receiver of the function from the stack into r1. 208 // Get the receiver of the function from the stack into r1.
208 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); 209 __ ldr(r1, MemOperand(sp, argc * kPointerSize));
209 // Get the name of the function from the stack; 1 ~ receiver.
210 __ ldr(r2, MemOperand(sp, (argc + 1) * kPointerSize));
211 210
212 // Probe the stub cache. 211 // Probe the stub cache.
213 Code::Flags flags = 212 Code::Flags flags =
214 Code::ComputeFlags(Code::CALL_IC, NOT_IN_LOOP, MONOMORPHIC, NORMAL, argc); 213 Code::ComputeFlags(Code::CALL_IC, NOT_IN_LOOP, MONOMORPHIC, NORMAL, argc);
215 StubCache::GenerateProbe(masm, flags, r1, r2, r3, no_reg); 214 StubCache::GenerateProbe(masm, flags, r1, r2, r3, no_reg);
216 215
217 // If the stub cache probing failed, the receiver might be a value. 216 // If the stub cache probing failed, the receiver might be a value.
218 // For value objects, we use the map of the prototype objects for 217 // For value objects, we use the map of the prototype objects for
219 // the corresponding JSValue for the cache and that is what we need 218 // the corresponding JSValue for the cache and that is what we need
220 // to probe. 219 // to probe.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 // Check that the value isn't a smi. 268 // Check that the value isn't a smi.
270 __ tst(r1, Operand(kSmiTagMask)); 269 __ tst(r1, Operand(kSmiTagMask));
271 __ b(eq, miss); 270 __ b(eq, miss);
272 271
273 // Check that the value is a JSFunction. 272 // Check that the value is a JSFunction.
274 __ CompareObjectType(r1, r0, r0, JS_FUNCTION_TYPE); 273 __ CompareObjectType(r1, r0, r0, JS_FUNCTION_TYPE);
275 __ b(ne, miss); 274 __ b(ne, miss);
276 275
277 // Patch the receiver with the global proxy if necessary. 276 // Patch the receiver with the global proxy if necessary.
278 if (is_global_object) { 277 if (is_global_object) {
279 __ ldr(r2, MemOperand(sp, argc * kPointerSize)); 278 __ ldr(r0, MemOperand(sp, argc * kPointerSize));
280 __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset)); 279 __ ldr(r0, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset));
281 __ str(r2, MemOperand(sp, argc * kPointerSize)); 280 __ str(r0, MemOperand(sp, argc * kPointerSize));
282 } 281 }
283 282
284 // Invoke the function. 283 // Invoke the function.
285 ParameterCount actual(argc); 284 ParameterCount actual(argc);
286 __ InvokeFunction(r1, actual, JUMP_FUNCTION); 285 __ InvokeFunction(r1, actual, JUMP_FUNCTION);
287 } 286 }
288 287
289 288
290 void CallIC::GenerateNormal(MacroAssembler* masm, int argc) { 289 void CallIC::GenerateNormal(MacroAssembler* masm, int argc) {
291 // ----------- S t a t e ------------- 290 // ----------- S t a t e -------------
292 // -- lr: return address 291 // -- r2 : name
292 // -- lr : return address
293 // ----------------------------------- 293 // -----------------------------------
294 Label miss, global_object, non_global_object; 294 Label miss, global_object, non_global_object;
295 295
296 // Get the receiver of the function from the stack into r1. 296 // Get the receiver of the function from the stack into r1.
297 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); 297 __ ldr(r1, MemOperand(sp, argc * kPointerSize));
298 // Get the name of the function from the stack; 1 ~ receiver.
299 __ ldr(r2, MemOperand(sp, (argc + 1) * kPointerSize));
300 298
301 // Check that the receiver isn't a smi. 299 // Check that the receiver isn't a smi.
302 __ tst(r1, Operand(kSmiTagMask)); 300 __ tst(r1, Operand(kSmiTagMask));
303 __ b(eq, &miss); 301 __ b(eq, &miss);
304 302
305 // Check that the receiver is a valid JS object. Put the map in r3. 303 // Check that the receiver is a valid JS object. Put the map in r3.
306 __ CompareObjectType(r1, r3, r0, FIRST_JS_OBJECT_TYPE); 304 __ CompareObjectType(r1, r3, r0, FIRST_JS_OBJECT_TYPE);
307 __ b(lt, &miss); 305 __ b(lt, &miss);
308 306
309 // If this assert fails, we have to check upper bound too. 307 // If this assert fails, we have to check upper bound too.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 __ b(&invoke); 340 __ b(&invoke);
343 341
344 // Cache miss: Jump to runtime. 342 // Cache miss: Jump to runtime.
345 __ bind(&miss); 343 __ bind(&miss);
346 GenerateMiss(masm, argc); 344 GenerateMiss(masm, argc);
347 } 345 }
348 346
349 347
350 void CallIC::GenerateMiss(MacroAssembler* masm, int argc) { 348 void CallIC::GenerateMiss(MacroAssembler* masm, int argc) {
351 // ----------- S t a t e ------------- 349 // ----------- S t a t e -------------
352 // -- lr: return address 350 // -- r2 : name
351 // -- lr : return address
353 // ----------------------------------- 352 // -----------------------------------
354 353
355 // Get the receiver of the function from the stack. 354 // Get the receiver of the function from the stack.
356 __ ldr(r2, MemOperand(sp, argc * kPointerSize)); 355 __ ldr(r3, MemOperand(sp, argc * kPointerSize));
357 // Get the name of the function to call from the stack.
358 __ ldr(r1, MemOperand(sp, (argc + 1) * kPointerSize));
359 356
360 __ EnterInternalFrame(); 357 __ EnterInternalFrame();
361 358
362 // Push the receiver and the name of the function. 359 // Push the receiver and the name of the function.
363 __ stm(db_w, sp, r1.bit() | r2.bit()); 360 __ stm(db_w, sp, r2.bit() | r3.bit());
364 361
365 // Call the entry. 362 // Call the entry.
366 __ mov(r0, Operand(2)); 363 __ mov(r0, Operand(2));
367 __ mov(r1, Operand(ExternalReference(IC_Utility(kCallIC_Miss)))); 364 __ mov(r1, Operand(ExternalReference(IC_Utility(kCallIC_Miss))));
368 365
369 CEntryStub stub(1); 366 CEntryStub stub(1);
370 __ CallStub(&stub); 367 __ CallStub(&stub);
371 368
372 // Move result to r1 and leave the internal frame. 369 // Move result to r1 and leave the internal frame.
373 __ mov(r1, Operand(r0)); 370 __ mov(r1, Operand(r0));
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 // ----------------------------------- 403 // -----------------------------------
407 404
408 __ ldr(r0, MemOperand(sp, 0)); 405 __ ldr(r0, MemOperand(sp, 0));
409 // Probe the stub cache. 406 // Probe the stub cache.
410 Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, 407 Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC,
411 NOT_IN_LOOP, 408 NOT_IN_LOOP,
412 MONOMORPHIC); 409 MONOMORPHIC);
413 StubCache::GenerateProbe(masm, flags, r0, r2, r3, no_reg); 410 StubCache::GenerateProbe(masm, flags, r0, r2, r3, no_reg);
414 411
415 // Cache miss: Jump to runtime. 412 // Cache miss: Jump to runtime.
416 Generate(masm, ExternalReference(IC_Utility(kLoadIC_Miss))); 413 GenerateMiss(masm);
417 } 414 }
418 415
419 416
420 void LoadIC::GenerateNormal(MacroAssembler* masm) { 417 void LoadIC::GenerateNormal(MacroAssembler* masm) {
421 // ----------- S t a t e ------------- 418 // ----------- S t a t e -------------
422 // -- r2 : name 419 // -- r2 : name
423 // -- lr : return address 420 // -- lr : return address
424 // -- [sp] : receiver 421 // -- [sp] : receiver
425 // ----------------------------------- 422 // -----------------------------------
426 Label miss, probe, global; 423 Label miss, probe, global;
(...skipping 22 matching lines...) Expand all
449 GenerateDictionaryLoad(masm, &miss, r1, r0); 446 GenerateDictionaryLoad(masm, &miss, r1, r0);
450 __ Ret(); 447 __ Ret();
451 448
452 // Global object access: Check access rights. 449 // Global object access: Check access rights.
453 __ bind(&global); 450 __ bind(&global);
454 __ CheckAccessGlobalProxy(r0, r1, &miss); 451 __ CheckAccessGlobalProxy(r0, r1, &miss);
455 __ b(&probe); 452 __ b(&probe);
456 453
457 // Cache miss: Restore receiver from stack and jump to runtime. 454 // Cache miss: Restore receiver from stack and jump to runtime.
458 __ bind(&miss); 455 __ bind(&miss);
459 Generate(masm, ExternalReference(IC_Utility(kLoadIC_Miss))); 456 GenerateMiss(masm);
460 } 457 }
461 458
462 459
463 void LoadIC::GenerateMiss(MacroAssembler* masm) { 460 void LoadIC::GenerateMiss(MacroAssembler* masm) {
464 Generate(masm, ExternalReference(IC_Utility(kLoadIC_Miss)));
465 }
466
467
468 void LoadIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
469 // ----------- S t a t e ------------- 461 // ----------- S t a t e -------------
470 // -- r2 : name 462 // -- r2 : name
471 // -- lr : return address 463 // -- lr : return address
472 // -- [sp] : receiver 464 // -- [sp] : receiver
473 // ----------------------------------- 465 // -----------------------------------
474 466
475 __ ldr(r3, MemOperand(sp, 0)); 467 __ ldr(r3, MemOperand(sp, 0));
476 __ stm(db_w, sp, r2.bit() | r3.bit()); 468 __ stm(db_w, sp, r2.bit() | r3.bit());
477 469
478 // Perform tail call to the entry. 470 // Perform tail call to the entry.
479 __ TailCallRuntime(f, 2, 1); 471 __ TailCallRuntime(ExternalReference(IC_Utility(kLoadIC_Miss)), 2, 1);
480 } 472 }
481 473
482 474
483 // TODO(181): Implement map patching once loop nesting is tracked on the 475 // TODO(181): Implement map patching once loop nesting is tracked on the
484 // ARM platform so we can generate inlined fast-case code loads in 476 // ARM platform so we can generate inlined fast-case code loads in
485 // loops. 477 // loops.
486 void LoadIC::ClearInlinedVersion(Address address) {} 478 void LoadIC::ClearInlinedVersion(Address address) {}
487 bool LoadIC::PatchInlinedLoad(Address address, Object* map, int offset) { 479 bool LoadIC::PatchInlinedLoad(Address address, Object* map, int offset) {
488 return false; 480 return false;
489 } 481 }
490 482
491 void KeyedLoadIC::ClearInlinedVersion(Address address) {} 483 void KeyedLoadIC::ClearInlinedVersion(Address address) {}
492 bool KeyedLoadIC::PatchInlinedLoad(Address address, Object* map) { 484 bool KeyedLoadIC::PatchInlinedLoad(Address address, Object* map) {
493 return false; 485 return false;
494 } 486 }
495 487
496 void KeyedStoreIC::ClearInlinedVersion(Address address) {} 488 void KeyedStoreIC::ClearInlinedVersion(Address address) {}
497 void KeyedStoreIC::RestoreInlinedVersion(Address address) {} 489 void KeyedStoreIC::RestoreInlinedVersion(Address address) {}
498 bool KeyedStoreIC::PatchInlinedStore(Address address, Object* map) { 490 bool KeyedStoreIC::PatchInlinedStore(Address address, Object* map) {
499 return false; 491 return false;
500 } 492 }
501 493
502 494
503 Object* KeyedLoadIC_Miss(Arguments args); 495 Object* KeyedLoadIC_Miss(Arguments args);
504 496
505 497
506 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { 498 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
507 Generate(masm, ExternalReference(IC_Utility(kKeyedLoadIC_Miss))); 499 // ---------- S t a t e --------------
500 // -- lr : return address
501 // -- sp[0] : key
502 // -- sp[4] : receiver
503 // -----------------------------------
504
505 __ ldm(ia, sp, r2.bit() | r3.bit());
506 __ stm(db_w, sp, r2.bit() | r3.bit());
507
508 __ TailCallRuntime(ExternalReference(IC_Utility(kKeyedLoadIC_Miss)), 2, 1);
508 } 509 }
509 510
510 511
511 void KeyedLoadIC::Generate(MacroAssembler* masm, const ExternalReference& f) { 512 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
512 // ---------- S t a t e -------------- 513 // ---------- S t a t e --------------
513 // -- lr : return address 514 // -- lr : return address
514 // -- sp[0] : key 515 // -- sp[0] : key
515 // -- sp[4] : receiver 516 // -- sp[4] : receiver
516 // ----------------------------------- 517 // -----------------------------------
517 518
518 __ ldm(ia, sp, r2.bit() | r3.bit()); 519 __ ldm(ia, sp, r2.bit() | r3.bit());
519 __ stm(db_w, sp, r2.bit() | r3.bit()); 520 __ stm(db_w, sp, r2.bit() | r3.bit());
520 521
521 __ TailCallRuntime(f, 2, 1); 522 __ TailCallRuntime(ExternalReference(Runtime::kGetProperty), 2, 1);
522 } 523 }
523 524
524 525
525 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { 526 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
526 // ---------- S t a t e -------------- 527 // ---------- S t a t e --------------
527 // -- lr : return address 528 // -- lr : return address
528 // -- sp[0] : key 529 // -- sp[0] : key
529 // -- sp[4] : receiver 530 // -- sp[4] : receiver
530 // ----------------------------------- 531 // -----------------------------------
531 Label slow, fast; 532 Label slow, fast;
532 533
533 // Get the key and receiver object from the stack. 534 // Get the key and receiver object from the stack.
534 __ ldm(ia, sp, r0.bit() | r1.bit()); 535 __ ldm(ia, sp, r0.bit() | r1.bit());
535 // Check that the key is a smi. 536
536 __ tst(r0, Operand(kSmiTagMask));
537 __ b(ne, &slow);
538 __ mov(r0, Operand(r0, ASR, kSmiTagSize));
539 // Check that the object isn't a smi. 537 // Check that the object isn't a smi.
540 __ tst(r1, Operand(kSmiTagMask)); 538 __ BranchOnSmi(r1, &slow);
541 __ b(eq, &slow);
542
543 // Get the map of the receiver. 539 // Get the map of the receiver.
544 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); 540 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset));
545
546 // Check bit field. 541 // Check bit field.
547 __ ldrb(r3, FieldMemOperand(r2, Map::kBitFieldOffset)); 542 __ ldrb(r3, FieldMemOperand(r2, Map::kBitFieldOffset));
548 __ tst(r3, Operand(kSlowCaseBitFieldMask)); 543 __ tst(r3, Operand(kSlowCaseBitFieldMask));
549 __ b(ne, &slow); 544 __ b(ne, &slow);
550 // Check that the object is some kind of JS object EXCEPT JS Value type. 545 // Check that the object is some kind of JS object EXCEPT JS Value type.
551 // In the case that the object is a value-wrapper object, 546 // In the case that the object is a value-wrapper object,
552 // we enter the runtime system to make sure that indexing into string 547 // we enter the runtime system to make sure that indexing into string
553 // objects work as intended. 548 // objects work as intended.
554 ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE); 549 ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE);
555 __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset)); 550 __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset));
556 __ cmp(r2, Operand(JS_OBJECT_TYPE)); 551 __ cmp(r2, Operand(JS_OBJECT_TYPE));
557 __ b(lt, &slow); 552 __ b(lt, &slow);
558 553
554 // Check that the key is a smi.
555 __ BranchOnNotSmi(r0, &slow);
556 __ mov(r0, Operand(r0, ASR, kSmiTagSize));
557
559 // Get the elements array of the object. 558 // Get the elements array of the object.
560 __ ldr(r1, FieldMemOperand(r1, JSObject::kElementsOffset)); 559 __ ldr(r1, FieldMemOperand(r1, JSObject::kElementsOffset));
561 // Check that the object is in fast mode (not dictionary). 560 // Check that the object is in fast mode (not dictionary).
562 __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset)); 561 __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset));
563 __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex); 562 __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex);
564 __ cmp(r3, ip); 563 __ cmp(r3, ip);
565 __ b(ne, &slow); 564 __ b(ne, &slow);
566 // Check that the key (index) is within bounds. 565 // Check that the key (index) is within bounds.
567 __ ldr(r3, FieldMemOperand(r1, Array::kLengthOffset)); 566 __ ldr(r3, FieldMemOperand(r1, Array::kLengthOffset));
568 __ cmp(r0, Operand(r3)); 567 __ cmp(r0, Operand(r3));
569 __ b(lo, &fast); 568 __ b(lo, &fast);
570 569
571 // Slow case: Push extra copies of the arguments (2). 570 // Slow case: Push extra copies of the arguments (2).
572 __ bind(&slow); 571 __ bind(&slow);
573 __ IncrementCounter(&Counters::keyed_load_generic_slow, 1, r0, r1); 572 __ IncrementCounter(&Counters::keyed_load_generic_slow, 1, r0, r1);
574 __ ldm(ia, sp, r0.bit() | r1.bit()); 573 GenerateRuntimeGetProperty(masm);
575 __ stm(db_w, sp, r0.bit() | r1.bit());
576 // Do tail-call to runtime routine.
577 __ TailCallRuntime(ExternalReference(Runtime::kGetProperty), 2, 1);
578 574
579 // Fast case: Do the load. 575 // Fast case: Do the load.
580 __ bind(&fast); 576 __ bind(&fast);
581 __ add(r3, r1, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 577 __ add(r3, r1, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
582 __ ldr(r0, MemOperand(r3, r0, LSL, kPointerSizeLog2)); 578 __ ldr(r0, MemOperand(r3, r0, LSL, kPointerSizeLog2));
583 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 579 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
584 __ cmp(r0, ip); 580 __ cmp(r0, ip);
585 // In case the loaded value is the_hole we have to consult GetProperty 581 // In case the loaded value is the_hole we have to consult GetProperty
586 // to ensure the prototype chain is searched. 582 // to ensure the prototype chain is searched.
587 __ b(eq, &slow); 583 __ b(eq, &slow);
(...skipping 13 matching lines...) Expand all
601 } 597 }
602 598
603 599
604 void KeyedLoadIC::GenerateExternalArray(MacroAssembler* masm, 600 void KeyedLoadIC::GenerateExternalArray(MacroAssembler* masm,
605 ExternalArrayType array_type) { 601 ExternalArrayType array_type) {
606 // TODO(476): port specialized code. 602 // TODO(476): port specialized code.
607 GenerateGeneric(masm); 603 GenerateGeneric(masm);
608 } 604 }
609 605
610 606
611 void KeyedStoreIC::Generate(MacroAssembler* masm, 607 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
612 const ExternalReference& f) { 608 // ---------- S t a t e --------------
609 // -- lr : return address
610 // -- sp[0] : key
611 // -- sp[4] : receiver
612 // -----------------------------------
613 Label slow;
614
615 // Get the key and receiver object from the stack.
616 __ ldm(ia, sp, r0.bit() | r1.bit());
617
618 // Check that the receiver isn't a smi.
619 __ BranchOnSmi(r1, &slow);
620
621 // Check that the key is a smi.
622 __ BranchOnNotSmi(r0, &slow);
623
624 // Get the map of the receiver.
625 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset));
626
627 // Check that it has indexed interceptor and access checks
628 // are not enabled for this object.
629 __ ldrb(r3, FieldMemOperand(r2, Map::kBitFieldOffset));
630 __ and_(r3, r3, Operand(kSlowCaseBitFieldMask));
631 __ cmp(r3, Operand(1 << Map::kHasIndexedInterceptor));
632 __ b(ne, &slow);
633
634 // Everything is fine, call runtime.
635 __ push(r1); // receiver
636 __ push(r0); // key
637
638 // Perform tail call to the entry.
639 __ TailCallRuntime(ExternalReference(
640 IC_Utility(kKeyedLoadPropertyWithInterceptor)), 2, 1);
641
642 __ bind(&slow);
643 GenerateMiss(masm);
644 }
645
646
647 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
613 // ---------- S t a t e -------------- 648 // ---------- S t a t e --------------
614 // -- r0 : value 649 // -- r0 : value
615 // -- lr : return address 650 // -- lr : return address
616 // -- sp[0] : key 651 // -- sp[0] : key
617 // -- sp[1] : receiver 652 // -- sp[1] : receiver
618 // ----------------------------------- 653 // -----------------------------------
619 654
620 __ ldm(ia, sp, r2.bit() | r3.bit()); 655 __ ldm(ia, sp, r2.bit() | r3.bit());
621 __ stm(db_w, sp, r0.bit() | r2.bit() | r3.bit()); 656 __ stm(db_w, sp, r0.bit() | r2.bit() | r3.bit());
622 657
623 __ TailCallRuntime(f, 3, 1); 658 __ TailCallRuntime(ExternalReference(IC_Utility(kKeyedStoreIC_Miss)), 3, 1);
659 }
660
661
662 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm) {
663 // ---------- S t a t e --------------
664 // -- r0 : value
665 // -- lr : return address
666 // -- sp[0] : key
667 // -- sp[1] : receiver
668 // -----------------------------------
669 __ ldm(ia, sp, r1.bit() | r3.bit()); // r0 == value, r1 == key, r3 == object
670 __ stm(db_w, sp, r0.bit() | r1.bit() | r3.bit());
671
672 __ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3, 1);
624 } 673 }
625 674
626 675
627 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) { 676 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
628 // ---------- S t a t e -------------- 677 // ---------- S t a t e --------------
629 // -- r0 : value 678 // -- r0 : value
630 // -- lr : return address 679 // -- lr : return address
631 // -- sp[0] : key 680 // -- sp[0] : key
632 // -- sp[1] : receiver 681 // -- sp[1] : receiver
633 // ----------------------------------- 682 // -----------------------------------
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
668 // Untag the key (for checking against untagged length in the fixed array). 717 // Untag the key (for checking against untagged length in the fixed array).
669 __ mov(r1, Operand(r1, ASR, kSmiTagSize)); 718 __ mov(r1, Operand(r1, ASR, kSmiTagSize));
670 // Compute address to store into and check array bounds. 719 // Compute address to store into and check array bounds.
671 __ add(r2, r3, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 720 __ add(r2, r3, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
672 __ add(r2, r2, Operand(r1, LSL, kPointerSizeLog2)); 721 __ add(r2, r2, Operand(r1, LSL, kPointerSizeLog2));
673 __ ldr(ip, FieldMemOperand(r3, FixedArray::kLengthOffset)); 722 __ ldr(ip, FieldMemOperand(r3, FixedArray::kLengthOffset));
674 __ cmp(r1, Operand(ip)); 723 __ cmp(r1, Operand(ip));
675 __ b(lo, &fast); 724 __ b(lo, &fast);
676 725
677 726
678 // Slow case: Push extra copies of the arguments (3). 727 // Slow case:
679 __ bind(&slow); 728 __ bind(&slow);
680 __ ldm(ia, sp, r1.bit() | r3.bit()); // r0 == value, r1 == key, r3 == object 729 GenerateRuntimeSetProperty(masm);
681 __ stm(db_w, sp, r0.bit() | r1.bit() | r3.bit());
682 // Do tail-call to runtime routine.
683 __ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3, 1);
684 730
685 // Extra capacity case: Check if there is extra capacity to 731 // Extra capacity case: Check if there is extra capacity to
686 // perform the store and update the length. Used for adding one 732 // perform the store and update the length. Used for adding one
687 // element to the array by writing to array[array.length]. 733 // element to the array by writing to array[array.length].
688 // r0 == value, r1 == key, r2 == elements, r3 == object 734 // r0 == value, r1 == key, r2 == elements, r3 == object
689 __ bind(&extra); 735 __ bind(&extra);
690 __ b(ne, &slow); // do not leave holes in the array 736 __ b(ne, &slow); // do not leave holes in the array
691 __ mov(r1, Operand(r1, ASR, kSmiTagSize)); // untag 737 __ mov(r1, Operand(r1, ASR, kSmiTagSize)); // untag
692 __ ldr(ip, FieldMemOperand(r2, Array::kLengthOffset)); 738 __ ldr(ip, FieldMemOperand(r2, Array::kLengthOffset));
693 __ cmp(r1, Operand(ip)); 739 __ cmp(r1, Operand(ip));
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 } 790 }
745 791
746 792
747 void KeyedStoreIC::GenerateExternalArray(MacroAssembler* masm, 793 void KeyedStoreIC::GenerateExternalArray(MacroAssembler* masm,
748 ExternalArrayType array_type) { 794 ExternalArrayType array_type) {
749 // TODO(476): port specialized code. 795 // TODO(476): port specialized code.
750 GenerateGeneric(masm); 796 GenerateGeneric(masm);
751 } 797 }
752 798
753 799
754 void KeyedStoreIC::GenerateExtendStorage(MacroAssembler* masm) {
755 // ---------- S t a t e --------------
756 // -- r0 : value
757 // -- lr : return address
758 // -- sp[0] : key
759 // -- sp[1] : receiver
760 // ----------- S t a t e -------------
761
762 __ ldm(ia, sp, r2.bit() | r3.bit());
763 __ stm(db_w, sp, r0.bit() | r2.bit() | r3.bit());
764
765 // Perform tail call to the entry.
766 __ TailCallRuntime(
767 ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
768 }
769
770
771 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { 800 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
772 // ----------- S t a t e ------------- 801 // ----------- S t a t e -------------
773 // -- r0 : value 802 // -- r0 : value
803 // -- r1 : receiver
774 // -- r2 : name 804 // -- r2 : name
775 // -- lr : return address 805 // -- lr : return address
776 // -- [sp] : receiver
777 // ----------------------------------- 806 // -----------------------------------
778 807
779 // Get the receiver from the stack and probe the stub cache. 808 // Get the receiver from the stack and probe the stub cache.
780 __ ldr(r1, MemOperand(sp));
781 Code::Flags flags = Code::ComputeFlags(Code::STORE_IC, 809 Code::Flags flags = Code::ComputeFlags(Code::STORE_IC,
782 NOT_IN_LOOP, 810 NOT_IN_LOOP,
783 MONOMORPHIC); 811 MONOMORPHIC);
784 StubCache::GenerateProbe(masm, flags, r1, r2, r3, no_reg); 812 StubCache::GenerateProbe(masm, flags, r1, r2, r3, no_reg);
785 813
786 // Cache miss: Jump to runtime. 814 // Cache miss: Jump to runtime.
787 GenerateMiss(masm); 815 GenerateMiss(masm);
788 } 816 }
789 817
790 818
791 void StoreIC::GenerateExtendStorage(MacroAssembler* masm) {
792 // ----------- S t a t e -------------
793 // -- r0 : value
794 // -- r2 : name
795 // -- lr : return address
796 // -- [sp] : receiver
797 // -----------------------------------
798
799 __ ldr(r3, MemOperand(sp)); // copy receiver
800 __ stm(db_w, sp, r0.bit() | r2.bit() | r3.bit());
801
802 // Perform tail call to the entry.
803 __ TailCallRuntime(
804 ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
805 }
806
807
808 void StoreIC::GenerateMiss(MacroAssembler* masm) { 819 void StoreIC::GenerateMiss(MacroAssembler* masm) {
809 // ----------- S t a t e ------------- 820 // ----------- S t a t e -------------
810 // -- r0 : value 821 // -- r0 : value
822 // -- r1 : receiver
811 // -- r2 : name 823 // -- r2 : name
812 // -- lr : return address 824 // -- lr : return address
813 // -- [sp] : receiver
814 // ----------------------------------- 825 // -----------------------------------
815 826
816 __ ldr(r3, MemOperand(sp)); // copy receiver 827 __ push(r1);
817 __ stm(db_w, sp, r0.bit() | r2.bit() | r3.bit()); 828 __ stm(db_w, sp, r2.bit() | r0.bit());
818 829
819 // Perform tail call to the entry. 830 // Perform tail call to the entry.
820 __ TailCallRuntime(ExternalReference(IC_Utility(kStoreIC_Miss)), 3, 1); 831 __ TailCallRuntime(ExternalReference(IC_Utility(kStoreIC_Miss)), 3, 1);
821 } 832 }
822 833
823 834
835 void StoreIC::GenerateArrayLength(MacroAssembler* masm) {
836 // ----------- S t a t e -------------
837 // -- r0 : value
838 // -- r1 : receiver
839 // -- r2 : name
840 // -- lr : return address
841 // -----------------------------------
842 //
843 // This accepts as a receiver anything JSObject::SetElementsLength accepts
844 // (currently anything except for external and pixel arrays which means
845 // anything with elements of FixedArray type.), but currently is restricted
846 // to JSArray.
847 // Value must be a number, but only smis are accepted as the most common case.
848
849 Label miss;
850
851 Register receiver = r1;
852 Register value = r0;
853 Register scratch = r3;
854
855 // Check that the receiver isn't a smi.
856 __ BranchOnSmi(receiver, &miss);
857
858 // Check that the object is a JS array.
859 __ CompareObjectType(receiver, scratch, scratch, JS_ARRAY_TYPE);
860 __ b(ne, &miss);
861
862 // Check that elements are FixedArray.
863 __ ldr(scratch, FieldMemOperand(receiver, JSArray::kElementsOffset));
864 __ CompareObjectType(scratch, scratch, scratch, FIXED_ARRAY_TYPE);
865 __ b(ne, &miss);
866
867 // Check that value is a smi.
868 __ BranchOnNotSmi(value, &miss);
869
870 // Prepare tail call to StoreIC_ArrayLength.
871 __ push(receiver);
872 __ push(value);
873
874 __ TailCallRuntime(ExternalReference(IC_Utility(kStoreIC_ArrayLength)), 2, 1);
875
876 __ bind(&miss);
877
878 GenerateMiss(masm);
879 }
880
881
824 #undef __ 882 #undef __
825 883
826 884
827 } } // namespace v8::internal 885 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/full-codegen-arm.cc ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698