| 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 18 matching lines...) Expand all Loading... |
| 29 | 29 |
| 30 #if defined(V8_TARGET_ARCH_ARM) | 30 #if defined(V8_TARGET_ARCH_ARM) |
| 31 | 31 |
| 32 #include "bootstrapper.h" | 32 #include "bootstrapper.h" |
| 33 #include "code-stubs.h" | 33 #include "code-stubs.h" |
| 34 #include "codegen-inl.h" | 34 #include "codegen-inl.h" |
| 35 #include "compiler.h" | 35 #include "compiler.h" |
| 36 #include "debug.h" | 36 #include "debug.h" |
| 37 #include "ic-inl.h" | 37 #include "ic-inl.h" |
| 38 #include "jsregexp.h" | 38 #include "jsregexp.h" |
| 39 #include "jump-target-light-inl.h" | 39 #include "jump-target-inl.h" |
| 40 #include "parser.h" | 40 #include "parser.h" |
| 41 #include "regexp-macro-assembler.h" | 41 #include "regexp-macro-assembler.h" |
| 42 #include "regexp-stack.h" | 42 #include "regexp-stack.h" |
| 43 #include "register-allocator-inl.h" | 43 #include "register-allocator-inl.h" |
| 44 #include "runtime.h" | 44 #include "runtime.h" |
| 45 #include "scopes.h" | 45 #include "scopes.h" |
| 46 #include "stub-cache.h" | 46 #include "stub-cache.h" |
| 47 #include "virtual-frame-inl.h" | 47 #include "virtual-frame-inl.h" |
| 48 #include "virtual-frame-arm-inl.h" | 48 #include "virtual-frame-arm-inl.h" |
| 49 | 49 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 72 | 72 |
| 73 void VirtualFrameRuntimeCallHelper::BeforeCall(MacroAssembler* masm) const { | 73 void VirtualFrameRuntimeCallHelper::BeforeCall(MacroAssembler* masm) const { |
| 74 frame_state_->frame()->AssertIsSpilled(); | 74 frame_state_->frame()->AssertIsSpilled(); |
| 75 } | 75 } |
| 76 | 76 |
| 77 | 77 |
| 78 void VirtualFrameRuntimeCallHelper::AfterCall(MacroAssembler* masm) const { | 78 void VirtualFrameRuntimeCallHelper::AfterCall(MacroAssembler* masm) const { |
| 79 } | 79 } |
| 80 | 80 |
| 81 | 81 |
| 82 void ICRuntimeCallHelper::BeforeCall(MacroAssembler* masm) const { | 82 void StubRuntimeCallHelper::BeforeCall(MacroAssembler* masm) const { |
| 83 masm->EnterInternalFrame(); | 83 masm->EnterInternalFrame(); |
| 84 } | 84 } |
| 85 | 85 |
| 86 | 86 |
| 87 void ICRuntimeCallHelper::AfterCall(MacroAssembler* masm) const { | 87 void StubRuntimeCallHelper::AfterCall(MacroAssembler* masm) const { |
| 88 masm->LeaveInternalFrame(); | 88 masm->LeaveInternalFrame(); |
| 89 } | 89 } |
| 90 | 90 |
| 91 | 91 |
| 92 // ------------------------------------------------------------------------- | 92 // ------------------------------------------------------------------------- |
| 93 // CodeGenState implementation. | 93 // CodeGenState implementation. |
| 94 | 94 |
| 95 CodeGenState::CodeGenState(CodeGenerator* owner) | 95 CodeGenState::CodeGenState(CodeGenerator* owner) |
| 96 : owner_(owner), | 96 : owner_(owner), |
| 97 previous_(owner->state()) { | 97 previous_(owner->state()) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 125 } | 125 } |
| 126 | 126 |
| 127 | 127 |
| 128 TypeInfoCodeGenState::~TypeInfoCodeGenState() { | 128 TypeInfoCodeGenState::~TypeInfoCodeGenState() { |
| 129 owner()->set_type_info(slot_, old_type_info_); | 129 owner()->set_type_info(slot_, old_type_info_); |
| 130 } | 130 } |
| 131 | 131 |
| 132 // ------------------------------------------------------------------------- | 132 // ------------------------------------------------------------------------- |
| 133 // CodeGenerator implementation | 133 // CodeGenerator implementation |
| 134 | 134 |
| 135 int CodeGenerator::inlined_write_barrier_size_ = -1; | |
| 136 | |
| 137 CodeGenerator::CodeGenerator(MacroAssembler* masm) | 135 CodeGenerator::CodeGenerator(MacroAssembler* masm) |
| 138 : deferred_(8), | 136 : deferred_(8), |
| 139 masm_(masm), | 137 masm_(masm), |
| 140 info_(NULL), | 138 info_(NULL), |
| 141 frame_(NULL), | 139 frame_(NULL), |
| 142 allocator_(NULL), | 140 allocator_(NULL), |
| 143 cc_reg_(al), | 141 cc_reg_(al), |
| 144 state_(NULL), | 142 state_(NULL), |
| 145 loop_nesting_(0), | 143 loop_nesting_(0), |
| 146 type_info_(NULL), | 144 type_info_(NULL), |
| (...skipping 11 matching lines...) Expand all Loading... |
| 158 void CodeGenerator::Generate(CompilationInfo* info) { | 156 void CodeGenerator::Generate(CompilationInfo* info) { |
| 159 // Record the position for debugging purposes. | 157 // Record the position for debugging purposes. |
| 160 CodeForFunctionPosition(info->function()); | 158 CodeForFunctionPosition(info->function()); |
| 161 Comment cmnt(masm_, "[ function compiled by virtual frame code generator"); | 159 Comment cmnt(masm_, "[ function compiled by virtual frame code generator"); |
| 162 | 160 |
| 163 // Initialize state. | 161 // Initialize state. |
| 164 info_ = info; | 162 info_ = info; |
| 165 | 163 |
| 166 int slots = scope()->num_parameters() + scope()->num_stack_slots(); | 164 int slots = scope()->num_parameters() + scope()->num_stack_slots(); |
| 167 ScopedVector<TypeInfo> type_info_array(slots); | 165 ScopedVector<TypeInfo> type_info_array(slots); |
| 166 for (int i = 0; i < slots; i++) { |
| 167 type_info_array[i] = TypeInfo::Unknown(); |
| 168 } |
| 168 type_info_ = &type_info_array; | 169 type_info_ = &type_info_array; |
| 169 | 170 |
| 170 ASSERT(allocator_ == NULL); | 171 ASSERT(allocator_ == NULL); |
| 171 RegisterAllocator register_allocator(this); | 172 RegisterAllocator register_allocator(this); |
| 172 allocator_ = ®ister_allocator; | 173 allocator_ = ®ister_allocator; |
| 173 ASSERT(frame_ == NULL); | 174 ASSERT(frame_ == NULL); |
| 174 frame_ = new VirtualFrame(); | 175 frame_ = new VirtualFrame(); |
| 175 cc_reg_ = al; | 176 cc_reg_ = al; |
| 176 | 177 |
| 177 // Adjust for function-level loop nesting. | 178 // Adjust for function-level loop nesting. |
| (...skipping 5237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5415 Load(args->at(2)); | 5416 Load(args->at(2)); |
| 5416 Load(args->at(3)); | 5417 Load(args->at(3)); |
| 5417 RegExpExecStub stub; | 5418 RegExpExecStub stub; |
| 5418 frame_->SpillAll(); | 5419 frame_->SpillAll(); |
| 5419 frame_->CallStub(&stub, 4); | 5420 frame_->CallStub(&stub, 4); |
| 5420 frame_->EmitPush(r0); | 5421 frame_->EmitPush(r0); |
| 5421 } | 5422 } |
| 5422 | 5423 |
| 5423 | 5424 |
| 5424 void CodeGenerator::GenerateRegExpConstructResult(ZoneList<Expression*>* args) { | 5425 void CodeGenerator::GenerateRegExpConstructResult(ZoneList<Expression*>* args) { |
| 5425 // No stub. This code only occurs a few times in regexp.js. | |
| 5426 const int kMaxInlineLength = 100; | |
| 5427 ASSERT_EQ(3, args->length()); | 5426 ASSERT_EQ(3, args->length()); |
| 5427 |
| 5428 Load(args->at(0)); // Size of array, smi. | 5428 Load(args->at(0)); // Size of array, smi. |
| 5429 Load(args->at(1)); // "index" property value. | 5429 Load(args->at(1)); // "index" property value. |
| 5430 Load(args->at(2)); // "input" property value. | 5430 Load(args->at(2)); // "input" property value. |
| 5431 { | 5431 RegExpConstructResultStub stub; |
| 5432 VirtualFrame::SpilledScope spilled_scope(frame_); | 5432 frame_->SpillAll(); |
| 5433 Label slowcase; | 5433 frame_->CallStub(&stub, 3); |
| 5434 Label done; | |
| 5435 __ ldr(r1, MemOperand(sp, kPointerSize * 2)); | |
| 5436 STATIC_ASSERT(kSmiTag == 0); | |
| 5437 STATIC_ASSERT(kSmiTagSize == 1); | |
| 5438 __ tst(r1, Operand(kSmiTagMask)); | |
| 5439 __ b(ne, &slowcase); | |
| 5440 __ cmp(r1, Operand(Smi::FromInt(kMaxInlineLength))); | |
| 5441 __ b(hi, &slowcase); | |
| 5442 // Smi-tagging is equivalent to multiplying by 2. | |
| 5443 // Allocate RegExpResult followed by FixedArray with size in ebx. | |
| 5444 // JSArray: [Map][empty properties][Elements][Length-smi][index][input] | |
| 5445 // Elements: [Map][Length][..elements..] | |
| 5446 // Size of JSArray with two in-object properties and the header of a | |
| 5447 // FixedArray. | |
| 5448 int objects_size = | |
| 5449 (JSRegExpResult::kSize + FixedArray::kHeaderSize) / kPointerSize; | |
| 5450 __ mov(r5, Operand(r1, LSR, kSmiTagSize + kSmiShiftSize)); | |
| 5451 __ add(r2, r5, Operand(objects_size)); | |
| 5452 __ AllocateInNewSpace( | |
| 5453 r2, // In: Size, in words. | |
| 5454 r0, // Out: Start of allocation (tagged). | |
| 5455 r3, // Scratch register. | |
| 5456 r4, // Scratch register. | |
| 5457 &slowcase, | |
| 5458 static_cast<AllocationFlags>(TAG_OBJECT | SIZE_IN_WORDS)); | |
| 5459 // r0: Start of allocated area, object-tagged. | |
| 5460 // r1: Number of elements in array, as smi. | |
| 5461 // r5: Number of elements, untagged. | |
| 5462 | |
| 5463 // Set JSArray map to global.regexp_result_map(). | |
| 5464 // Set empty properties FixedArray. | |
| 5465 // Set elements to point to FixedArray allocated right after the JSArray. | |
| 5466 // Interleave operations for better latency. | |
| 5467 __ ldr(r2, ContextOperand(cp, Context::GLOBAL_INDEX)); | |
| 5468 __ add(r3, r0, Operand(JSRegExpResult::kSize)); | |
| 5469 __ mov(r4, Operand(FACTORY->empty_fixed_array())); | |
| 5470 __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalContextOffset)); | |
| 5471 __ str(r3, FieldMemOperand(r0, JSObject::kElementsOffset)); | |
| 5472 __ ldr(r2, ContextOperand(r2, Context::REGEXP_RESULT_MAP_INDEX)); | |
| 5473 __ str(r4, FieldMemOperand(r0, JSObject::kPropertiesOffset)); | |
| 5474 __ str(r2, FieldMemOperand(r0, HeapObject::kMapOffset)); | |
| 5475 | |
| 5476 // Set input, index and length fields from arguments. | |
| 5477 __ ldm(ia_w, sp, static_cast<RegList>(r2.bit() | r4.bit())); | |
| 5478 __ str(r1, FieldMemOperand(r0, JSArray::kLengthOffset)); | |
| 5479 __ add(sp, sp, Operand(kPointerSize)); | |
| 5480 __ str(r4, FieldMemOperand(r0, JSRegExpResult::kIndexOffset)); | |
| 5481 __ str(r2, FieldMemOperand(r0, JSRegExpResult::kInputOffset)); | |
| 5482 | |
| 5483 // Fill out the elements FixedArray. | |
| 5484 // r0: JSArray, tagged. | |
| 5485 // r3: FixedArray, tagged. | |
| 5486 // r5: Number of elements in array, untagged. | |
| 5487 | |
| 5488 // Set map. | |
| 5489 __ mov(r2, Operand(FACTORY->fixed_array_map())); | |
| 5490 __ str(r2, FieldMemOperand(r3, HeapObject::kMapOffset)); | |
| 5491 // Set FixedArray length. | |
| 5492 __ mov(r6, Operand(r5, LSL, kSmiTagSize)); | |
| 5493 __ str(r6, FieldMemOperand(r3, FixedArray::kLengthOffset)); | |
| 5494 // Fill contents of fixed-array with the-hole. | |
| 5495 __ mov(r2, Operand(FACTORY->the_hole_value())); | |
| 5496 __ add(r3, r3, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | |
| 5497 // Fill fixed array elements with hole. | |
| 5498 // r0: JSArray, tagged. | |
| 5499 // r2: the hole. | |
| 5500 // r3: Start of elements in FixedArray. | |
| 5501 // r5: Number of elements to fill. | |
| 5502 Label loop; | |
| 5503 __ tst(r5, Operand(r5)); | |
| 5504 __ bind(&loop); | |
| 5505 __ b(le, &done); // Jump if r1 is negative or zero. | |
| 5506 __ sub(r5, r5, Operand(1), SetCC); | |
| 5507 __ str(r2, MemOperand(r3, r5, LSL, kPointerSizeLog2)); | |
| 5508 __ jmp(&loop); | |
| 5509 | |
| 5510 __ bind(&slowcase); | |
| 5511 __ CallRuntime(Runtime::kRegExpConstructResult, 3); | |
| 5512 | |
| 5513 __ bind(&done); | |
| 5514 } | |
| 5515 frame_->Forget(3); | |
| 5516 frame_->EmitPush(r0); | 5434 frame_->EmitPush(r0); |
| 5517 } | 5435 } |
| 5518 | 5436 |
| 5519 | 5437 |
| 5520 class DeferredSearchCache: public DeferredCode { | 5438 class DeferredSearchCache: public DeferredCode { |
| 5521 public: | 5439 public: |
| 5522 DeferredSearchCache(Register dst, Register cache, Register key) | 5440 DeferredSearchCache(Register dst, Register cache, Register key) |
| 5523 : dst_(dst), cache_(cache), key_(key) { | 5441 : dst_(dst), cache_(cache), key_(key) { |
| 5524 set_comment("[ DeferredSearchCache"); | 5442 set_comment("[ DeferredSearchCache"); |
| 5525 } | 5443 } |
| (...skipping 1544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7070 // Clobber all input registers when running with the debug-code flag | 6988 // Clobber all input registers when running with the debug-code flag |
| 7071 // turned on to provoke errors. | 6989 // turned on to provoke errors. |
| 7072 if (FLAG_debug_code) { | 6990 if (FLAG_debug_code) { |
| 7073 __ mov(receiver, Operand(BitCast<int32_t>(kZapValue))); | 6991 __ mov(receiver, Operand(BitCast<int32_t>(kZapValue))); |
| 7074 __ mov(scratch0, Operand(BitCast<int32_t>(kZapValue))); | 6992 __ mov(scratch0, Operand(BitCast<int32_t>(kZapValue))); |
| 7075 __ mov(scratch1, Operand(BitCast<int32_t>(kZapValue))); | 6993 __ mov(scratch1, Operand(BitCast<int32_t>(kZapValue))); |
| 7076 } | 6994 } |
| 7077 // Check that this is the first inlined write barrier or that | 6995 // Check that this is the first inlined write barrier or that |
| 7078 // this inlined write barrier has the same size as all the other | 6996 // this inlined write barrier has the same size as all the other |
| 7079 // inlined write barriers. | 6997 // inlined write barriers. |
| 7080 ASSERT((inlined_write_barrier_size_ == -1) || | 6998 ASSERT((Isolate::Current()->inlined_write_barrier_size() == -1) || |
| 7081 (inlined_write_barrier_size_ == | 6999 (Isolate::Current()->inlined_write_barrier_size() == |
| 7082 masm()->InstructionsGeneratedSince(&record_write_start))); | 7000 masm()->InstructionsGeneratedSince(&record_write_start))); |
| 7083 inlined_write_barrier_size_ = | 7001 Isolate::Current()->set_inlined_write_barrier_size( |
| 7084 masm()->InstructionsGeneratedSince(&record_write_start); | 7002 masm()->InstructionsGeneratedSince(&record_write_start)); |
| 7085 | 7003 |
| 7086 // Make sure that the expected number of instructions are generated. | 7004 // Make sure that the expected number of instructions are generated. |
| 7087 ASSERT_EQ(GetInlinedNamedStoreInstructionsAfterPatch(), | 7005 ASSERT_EQ(GetInlinedNamedStoreInstructionsAfterPatch(), |
| 7088 masm()->InstructionsGeneratedSince(&check_inlined_codesize)); | 7006 masm()->InstructionsGeneratedSince(&check_inlined_codesize)); |
| 7089 } | 7007 } |
| 7090 deferred->BindExit(); | 7008 deferred->BindExit(); |
| 7091 } | 7009 } |
| 7092 ASSERT_EQ(expected_height, frame()->height()); | 7010 ASSERT_EQ(expected_height, frame()->height()); |
| 7093 } | 7011 } |
| 7094 | 7012 |
| (...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7456 specialized_on_rhs_ ? "_ConstantRhs" : "", | 7374 specialized_on_rhs_ ? "_ConstantRhs" : "", |
| 7457 BinaryOpIC::GetName(runtime_operands_type_)); | 7375 BinaryOpIC::GetName(runtime_operands_type_)); |
| 7458 return name_; | 7376 return name_; |
| 7459 } | 7377 } |
| 7460 | 7378 |
| 7461 #undef __ | 7379 #undef __ |
| 7462 | 7380 |
| 7463 } } // namespace v8::internal | 7381 } } // namespace v8::internal |
| 7464 | 7382 |
| 7465 #endif // V8_TARGET_ARCH_ARM | 7383 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |