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 6546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6557 __ bind(&slowcase); | 6557 __ bind(&slowcase); |
6558 __ CallRuntime(Runtime::kRegExpConstructResult, 3); | 6558 __ CallRuntime(Runtime::kRegExpConstructResult, 3); |
6559 | 6559 |
6560 __ bind(&done); | 6560 __ bind(&done); |
6561 } | 6561 } |
6562 frame_->Forget(3); | 6562 frame_->Forget(3); |
6563 frame_->Push(rax); | 6563 frame_->Push(rax); |
6564 } | 6564 } |
6565 | 6565 |
6566 | 6566 |
6567 void CodeGenerator::GenerateRegExpCloneResult(ZoneList<Expression*>* args) { | |
6568 ASSERT_EQ(1, args->length()); | |
6569 | |
6570 Load(args->at(0)); | |
6571 Result object_result = frame_->Pop(); | |
6572 object_result.ToRegister(rax); | |
6573 object_result.Unuse(); | |
6574 { | |
6575 VirtualFrame::SpilledScope spilled_scope; | |
6576 | |
6577 Label done; | |
6578 __ JumpIfSmi(rax, &done); | |
6579 | |
6580 // Load JSRegExpResult map into rdx. | |
6581 // Arguments to this function should be results of calling RegExp exec, | |
6582 // which is either an unmodified JSRegExpResult or null. Anything not having | |
6583 // the unmodified JSRegExpResult map is returned unmodified. | |
6584 // This also ensures that elements are fast. | |
6585 | |
6586 __ movq(rdx, ContextOperand(rsi, Context::GLOBAL_INDEX)); | |
6587 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalContextOffset)); | |
6588 __ movq(rdx, ContextOperand(rdx, Context::REGEXP_RESULT_MAP_INDEX)); | |
6589 __ cmpq(rdx, FieldOperand(rax, HeapObject::kMapOffset)); | |
6590 __ j(not_equal, &done); | |
6591 | |
6592 if (FLAG_debug_code) { | |
6593 // Check that object really has empty properties array, as the map | |
6594 // should guarantee. | |
6595 __ CompareRoot(FieldOperand(rax, JSObject::kPropertiesOffset), | |
6596 Heap::kEmptyFixedArrayRootIndex); | |
6597 __ Check(equal, "JSRegExpResult: default map but non-empty properties."); | |
6598 } | |
6599 | |
6600 DeferredAllocateInNewSpace* allocate_fallback = | |
6601 new DeferredAllocateInNewSpace(JSRegExpResult::kSize, | |
6602 rbx, | |
6603 rdx.bit() | rax.bit()); | |
6604 | |
6605 // All set, copy the contents to a new object. | |
6606 __ AllocateInNewSpace(JSRegExpResult::kSize, | |
6607 rbx, | |
6608 no_reg, | |
6609 no_reg, | |
6610 allocate_fallback->entry_label(), | |
6611 TAG_OBJECT); | |
6612 __ bind(allocate_fallback->exit_label()); | |
6613 | |
6614 STATIC_ASSERT(JSRegExpResult::kSize % (2 * kPointerSize) == 0); | |
6615 // There is an even number of fields, so unroll the loop once | |
6616 // for efficiency. | |
6617 for (int i = 0; i < JSRegExpResult::kSize; i += 2 * kPointerSize) { | |
6618 STATIC_ASSERT(JSObject::kMapOffset % (2 * kPointerSize) == 0); | |
6619 if (i != JSObject::kMapOffset) { | |
6620 // The map was already loaded into edx. | |
6621 __ movq(rdx, FieldOperand(rax, i)); | |
6622 } | |
6623 __ movq(rcx, FieldOperand(rax, i + kPointerSize)); | |
6624 | |
6625 STATIC_ASSERT(JSObject::kElementsOffset % (2 * kPointerSize) == 0); | |
6626 if (i == JSObject::kElementsOffset) { | |
6627 // If the elements array isn't empty, make it copy-on-write | |
6628 // before copying it. | |
6629 Label empty; | |
6630 __ CompareRoot(rdx, Heap::kEmptyFixedArrayRootIndex); | |
6631 __ j(equal, &empty); | |
6632 __ LoadRoot(kScratchRegister, Heap::kFixedCOWArrayMapRootIndex); | |
6633 __ movq(FieldOperand(rdx, HeapObject::kMapOffset), kScratchRegister); | |
6634 __ bind(&empty); | |
6635 } | |
6636 __ movq(FieldOperand(rbx, i), rdx); | |
6637 __ movq(FieldOperand(rbx, i + kPointerSize), rcx); | |
6638 } | |
6639 __ movq(rax, rbx); | |
6640 | |
6641 __ bind(&done); | |
6642 } | |
6643 frame_->Push(rax); | |
6644 } | |
6645 | |
6646 | |
6647 class DeferredSearchCache: public DeferredCode { | 6567 class DeferredSearchCache: public DeferredCode { |
6648 public: | 6568 public: |
6649 DeferredSearchCache(Register dst, | 6569 DeferredSearchCache(Register dst, |
6650 Register cache, | 6570 Register cache, |
6651 Register key, | 6571 Register key, |
6652 Register scratch) | 6572 Register scratch) |
6653 : dst_(dst), cache_(cache), key_(key), scratch_(scratch) { | 6573 : dst_(dst), cache_(cache), key_(key), scratch_(scratch) { |
6654 set_comment("[ DeferredSearchCache"); | 6574 set_comment("[ DeferredSearchCache"); |
6655 } | 6575 } |
6656 | 6576 |
(...skipping 2279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8936 #undef __ | 8856 #undef __ |
8937 | 8857 |
8938 void RecordWriteStub::Generate(MacroAssembler* masm) { | 8858 void RecordWriteStub::Generate(MacroAssembler* masm) { |
8939 masm->RecordWriteHelper(object_, addr_, scratch_); | 8859 masm->RecordWriteHelper(object_, addr_, scratch_); |
8940 masm->ret(0); | 8860 masm->ret(0); |
8941 } | 8861 } |
8942 | 8862 |
8943 } } // namespace v8::internal | 8863 } } // namespace v8::internal |
8944 | 8864 |
8945 #endif // V8_TARGET_ARCH_X64 | 8865 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |