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

Side by Side Diff: src/arm/code-stubs-arm.h

Issue 7945009: Merge experimental/gc branch to the bleeding_edge. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 3 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/assembler-arm-inl.h ('k') | src/arm/code-stubs-arm.cc » ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 TranscendentalCache::Type type_; 51 TranscendentalCache::Type type_;
52 ArgumentType argument_type_; 52 ArgumentType argument_type_;
53 void GenerateCallCFunction(MacroAssembler* masm, Register scratch); 53 void GenerateCallCFunction(MacroAssembler* masm, Register scratch);
54 54
55 Major MajorKey() { return TranscendentalCache; } 55 Major MajorKey() { return TranscendentalCache; }
56 int MinorKey() { return type_ | argument_type_; } 56 int MinorKey() { return type_ | argument_type_; }
57 Runtime::FunctionId RuntimeFunction(); 57 Runtime::FunctionId RuntimeFunction();
58 }; 58 };
59 59
60 60
61 class StoreBufferOverflowStub: public CodeStub {
62 public:
63 explicit StoreBufferOverflowStub(SaveFPRegsMode save_fp)
64 : save_doubles_(save_fp) { }
65
66 void Generate(MacroAssembler* masm);
67
68 virtual bool CompilingCallsToThisStubIsGCSafe() { return true; }
69 static void GenerateFixedRegStubsAheadOfTime();
70 virtual bool SometimesSetsUpAFrame() { return false; }
71
72 private:
73 SaveFPRegsMode save_doubles_;
74
75 Major MajorKey() { return StoreBufferOverflow; }
76 int MinorKey() { return (save_doubles_ == kSaveFPRegs) ? 1 : 0; }
77 };
78
79
61 class UnaryOpStub: public CodeStub { 80 class UnaryOpStub: public CodeStub {
62 public: 81 public:
63 UnaryOpStub(Token::Value op, 82 UnaryOpStub(Token::Value op,
64 UnaryOverwriteMode mode, 83 UnaryOverwriteMode mode,
65 UnaryOpIC::TypeInfo operand_type = UnaryOpIC::UNINITIALIZED) 84 UnaryOpIC::TypeInfo operand_type = UnaryOpIC::UNINITIALIZED)
66 : op_(op), 85 : op_(op),
67 mode_(mode), 86 mode_(mode),
68 operand_type_(operand_type) { 87 operand_type_(operand_type) {
69 } 88 }
70 89
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 class WriteInt32ToHeapNumberStub : public CodeStub { 336 class WriteInt32ToHeapNumberStub : public CodeStub {
318 public: 337 public:
319 WriteInt32ToHeapNumberStub(Register the_int, 338 WriteInt32ToHeapNumberStub(Register the_int,
320 Register the_heap_number, 339 Register the_heap_number,
321 Register scratch) 340 Register scratch)
322 : the_int_(the_int), 341 : the_int_(the_int),
323 the_heap_number_(the_heap_number), 342 the_heap_number_(the_heap_number),
324 scratch_(scratch) { } 343 scratch_(scratch) { }
325 344
326 bool CompilingCallsToThisStubIsGCSafe(); 345 bool CompilingCallsToThisStubIsGCSafe();
327 static void GenerateStubsAheadOfTime(); 346 static void GenerateFixedRegStubsAheadOfTime();
328 347
329 private: 348 private:
330 Register the_int_; 349 Register the_int_;
331 Register the_heap_number_; 350 Register the_heap_number_;
332 Register scratch_; 351 Register scratch_;
333 352
334 // Minor key encoding in 16 bits. 353 // Minor key encoding in 16 bits.
335 class IntRegisterBits: public BitField<int, 0, 4> {}; 354 class IntRegisterBits: public BitField<int, 0, 4> {};
336 class HeapNumberRegisterBits: public BitField<int, 4, 4> {}; 355 class HeapNumberRegisterBits: public BitField<int, 4, 4> {};
337 class ScratchRegisterBits: public BitField<int, 8, 4> {}; 356 class ScratchRegisterBits: public BitField<int, 8, 4> {};
(...skipping 29 matching lines...) Expand all
367 Label* not_found); 386 Label* not_found);
368 387
369 private: 388 private:
370 Major MajorKey() { return NumberToString; } 389 Major MajorKey() { return NumberToString; }
371 int MinorKey() { return 0; } 390 int MinorKey() { return 0; }
372 391
373 void Generate(MacroAssembler* masm); 392 void Generate(MacroAssembler* masm);
374 }; 393 };
375 394
376 395
396 class RecordWriteStub: public CodeStub {
397 public:
398 RecordWriteStub(Register object,
399 Register value,
400 Register address,
401 RememberedSetAction remembered_set_action,
402 SaveFPRegsMode fp_mode)
403 : object_(object),
404 value_(value),
405 address_(address),
406 remembered_set_action_(remembered_set_action),
407 save_fp_regs_mode_(fp_mode),
408 regs_(object, // An input reg.
409 address, // An input reg.
410 value) { // One scratch reg.
411 }
412
413 enum Mode {
414 STORE_BUFFER_ONLY,
415 INCREMENTAL,
416 INCREMENTAL_COMPACTION
417 };
418
419 virtual bool CompilingCallsToThisStubIsGCSafe();
420 static void GenerateFixedRegStubsAheadOfTime();
421 virtual bool SometimesSetsUpAFrame() { return false; }
422
423 static void PatchBranchIntoNop(MacroAssembler* masm, int pos) {
424 masm->instr_at_put(pos, (masm->instr_at(pos) & ~B27) | (B24 | B20));
425 ASSERT(Assembler::IsTstImmediate(masm->instr_at(pos)));
426 }
427
428 static void PatchNopIntoBranch(MacroAssembler* masm, int pos) {
429 masm->instr_at_put(pos, (masm->instr_at(pos) & ~(B24 | B20)) | B27);
430 ASSERT(Assembler::IsBranch(masm->instr_at(pos)));
431 }
432
433 static Mode GetMode(Code* stub) {
434 Instr first_instruction = Assembler::instr_at(stub->instruction_start());
435 Instr second_instruction = Assembler::instr_at(stub->instruction_start() +
436 Assembler::kInstrSize);
437
438 if (Assembler::IsBranch(first_instruction)) {
439 return INCREMENTAL;
440 }
441
442 ASSERT(Assembler::IsTstImmediate(first_instruction));
443
444 if (Assembler::IsBranch(second_instruction)) {
445 return INCREMENTAL_COMPACTION;
446 }
447
448 ASSERT(Assembler::IsTstImmediate(second_instruction));
449
450 return STORE_BUFFER_ONLY;
451 }
452
453 static void Patch(Code* stub, Mode mode) {
454 MacroAssembler masm(NULL,
455 stub->instruction_start(),
456 stub->instruction_size());
457 switch (mode) {
458 case STORE_BUFFER_ONLY:
459 ASSERT(GetMode(stub) == INCREMENTAL ||
460 GetMode(stub) == INCREMENTAL_COMPACTION);
461 PatchBranchIntoNop(&masm, 0);
462 PatchBranchIntoNop(&masm, Assembler::kInstrSize);
463 break;
464 case INCREMENTAL:
465 ASSERT(GetMode(stub) == STORE_BUFFER_ONLY);
466 PatchNopIntoBranch(&masm, 0);
467 break;
468 case INCREMENTAL_COMPACTION:
469 ASSERT(GetMode(stub) == STORE_BUFFER_ONLY);
470 PatchNopIntoBranch(&masm, Assembler::kInstrSize);
471 break;
472 }
473 ASSERT(GetMode(stub) == mode);
474 CPU::FlushICache(stub->instruction_start(), 2 * Assembler::kInstrSize);
475 }
476
477 private:
478 // This is a helper class for freeing up 3 scratch registers. The input is
479 // two registers that must be preserved and one scratch register provided by
480 // the caller.
481 class RegisterAllocation {
482 public:
483 RegisterAllocation(Register object,
484 Register address,
485 Register scratch0)
486 : object_(object),
487 address_(address),
488 scratch0_(scratch0) {
489 ASSERT(!AreAliased(scratch0, object, address, no_reg));
490 scratch1_ = GetRegThatIsNotOneOf(object_, address_, scratch0_);
491 }
492
493 void Save(MacroAssembler* masm) {
494 ASSERT(!AreAliased(object_, address_, scratch1_, scratch0_));
495 // We don't have to save scratch0_ because it was given to us as
496 // a scratch register.
497 masm->push(scratch1_);
498 }
499
500 void Restore(MacroAssembler* masm) {
501 masm->pop(scratch1_);
502 }
503
504 // If we have to call into C then we need to save and restore all caller-
505 // saved registers that were not already preserved. The scratch registers
506 // will be restored by other means so we don't bother pushing them here.
507 void SaveCallerSaveRegisters(MacroAssembler* masm, SaveFPRegsMode mode) {
508 masm->stm(db_w, sp, (kCallerSaved | lr.bit()) & ~scratch1_.bit());
509 if (mode == kSaveFPRegs) {
510 CpuFeatures::Scope scope(VFP3);
511 masm->sub(sp,
512 sp,
513 Operand(kDoubleSize * (DwVfpRegister::kNumRegisters - 1)));
514 // Save all VFP registers except d0.
515 for (int i = DwVfpRegister::kNumRegisters - 1; i > 0; i--) {
516 DwVfpRegister reg = DwVfpRegister::from_code(i);
517 masm->vstr(reg, MemOperand(sp, (i - 1) * kDoubleSize));
518 }
519 }
520 }
521
522 inline void RestoreCallerSaveRegisters(MacroAssembler*masm,
523 SaveFPRegsMode mode) {
524 if (mode == kSaveFPRegs) {
525 CpuFeatures::Scope scope(VFP3);
526 // Restore all VFP registers except d0.
527 for (int i = DwVfpRegister::kNumRegisters - 1; i > 0; i--) {
528 DwVfpRegister reg = DwVfpRegister::from_code(i);
529 masm->vldr(reg, MemOperand(sp, (i - 1) * kDoubleSize));
530 }
531 masm->add(sp,
532 sp,
533 Operand(kDoubleSize * (DwVfpRegister::kNumRegisters - 1)));
534 }
535 masm->ldm(ia_w, sp, (kCallerSaved | lr.bit()) & ~scratch1_.bit());
536 }
537
538 inline Register object() { return object_; }
539 inline Register address() { return address_; }
540 inline Register scratch0() { return scratch0_; }
541 inline Register scratch1() { return scratch1_; }
542
543 private:
544 Register object_;
545 Register address_;
546 Register scratch0_;
547 Register scratch1_;
548
549 Register GetRegThatIsNotOneOf(Register r1,
550 Register r2,
551 Register r3) {
552 for (int i = 0; i < Register::kNumAllocatableRegisters; i++) {
553 Register candidate = Register::FromAllocationIndex(i);
554 if (candidate.is(r1)) continue;
555 if (candidate.is(r2)) continue;
556 if (candidate.is(r3)) continue;
557 return candidate;
558 }
559 UNREACHABLE();
560 return no_reg;
561 }
562 friend class RecordWriteStub;
563 };
564
565 enum OnNoNeedToInformIncrementalMarker {
566 kReturnOnNoNeedToInformIncrementalMarker,
567 kUpdateRememberedSetOnNoNeedToInformIncrementalMarker
568 };
569
570 void Generate(MacroAssembler* masm);
571 void GenerateIncremental(MacroAssembler* masm, Mode mode);
572 void CheckNeedsToInformIncrementalMarker(
573 MacroAssembler* masm,
574 OnNoNeedToInformIncrementalMarker on_no_need,
575 Mode mode);
576 void InformIncrementalMarker(MacroAssembler* masm, Mode mode);
577
578 Major MajorKey() { return RecordWrite; }
579
580 int MinorKey() {
581 return ObjectBits::encode(object_.code()) |
582 ValueBits::encode(value_.code()) |
583 AddressBits::encode(address_.code()) |
584 RememberedSetActionBits::encode(remembered_set_action_) |
585 SaveFPRegsModeBits::encode(save_fp_regs_mode_);
586 }
587
588 bool MustBeInStubCache() {
589 // All stubs must be registered in the stub cache
590 // otherwise IncrementalMarker would not be able to find
591 // and patch it.
592 return true;
593 }
594
595 void Activate(Code* code) {
596 code->GetHeap()->incremental_marking()->ActivateGeneratedStub(code);
597 }
598
599 class ObjectBits: public BitField<int, 0, 4> {};
600 class ValueBits: public BitField<int, 4, 4> {};
601 class AddressBits: public BitField<int, 8, 4> {};
602 class RememberedSetActionBits: public BitField<RememberedSetAction, 12, 1> {};
603 class SaveFPRegsModeBits: public BitField<SaveFPRegsMode, 13, 1> {};
604
605 Register object_;
606 Register value_;
607 Register address_;
608 RememberedSetAction remembered_set_action_;
609 SaveFPRegsMode save_fp_regs_mode_;
610 Label slow_;
611 RegisterAllocation regs_;
612 };
613
614
377 // Enter C code from generated RegExp code in a way that allows 615 // Enter C code from generated RegExp code in a way that allows
378 // the C code to fix the return address in case of a GC. 616 // the C code to fix the return address in case of a GC.
379 // Currently only needed on ARM. 617 // Currently only needed on ARM.
380 class RegExpCEntryStub: public CodeStub { 618 class RegExpCEntryStub: public CodeStub {
381 public: 619 public:
382 RegExpCEntryStub() {} 620 RegExpCEntryStub() {}
383 virtual ~RegExpCEntryStub() {} 621 virtual ~RegExpCEntryStub() {}
384 void Generate(MacroAssembler* masm); 622 void Generate(MacroAssembler* masm);
385 623
386 private: 624 private:
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 838
601 class LookupModeBits: public BitField<LookupMode, 0, 1> {}; 839 class LookupModeBits: public BitField<LookupMode, 0, 1> {};
602 840
603 LookupMode mode_; 841 LookupMode mode_;
604 }; 842 };
605 843
606 844
607 } } // namespace v8::internal 845 } } // namespace v8::internal
608 846
609 #endif // V8_ARM_CODE_STUBS_ARM_H_ 847 #endif // V8_ARM_CODE_STUBS_ARM_H_
OLDNEW
« no previous file with comments | « src/arm/assembler-arm-inl.h ('k') | src/arm/code-stubs-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698