| 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 3262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3273 __ ldr(tmp, frame_->Function()); | 3273 __ ldr(tmp, frame_->Function()); |
| 3274 | 3274 |
| 3275 // Load the literals array of the function. | 3275 // Load the literals array of the function. |
| 3276 __ ldr(tmp, FieldMemOperand(tmp, JSFunction::kLiteralsOffset)); | 3276 __ ldr(tmp, FieldMemOperand(tmp, JSFunction::kLiteralsOffset)); |
| 3277 | 3277 |
| 3278 // Load the literal at the ast saved index. | 3278 // Load the literal at the ast saved index. |
| 3279 int literal_offset = | 3279 int literal_offset = |
| 3280 FixedArray::kHeaderSize + node->literal_index() * kPointerSize; | 3280 FixedArray::kHeaderSize + node->literal_index() * kPointerSize; |
| 3281 __ ldr(literal, FieldMemOperand(tmp, literal_offset)); | 3281 __ ldr(literal, FieldMemOperand(tmp, literal_offset)); |
| 3282 | 3282 |
| 3283 JumpTarget done; | 3283 JumpTarget materialized; |
| 3284 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 3284 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
| 3285 __ cmp(literal, ip); | 3285 __ cmp(literal, ip); |
| 3286 // This branch locks the virtual frame at the done label to match the | 3286 // This branch locks the virtual frame at the done label to match the |
| 3287 // one we have here, where the literal register is not on the stack and | 3287 // one we have here, where the literal register is not on the stack and |
| 3288 // nothing is spilled. | 3288 // nothing is spilled. |
| 3289 done.Branch(ne); | 3289 materialized.Branch(ne); |
| 3290 | 3290 |
| 3291 // If the entry is undefined we call the runtime system to compute | 3291 // If the entry is undefined we call the runtime system to compute |
| 3292 // the literal. | 3292 // the literal. |
| 3293 // literal array (0) | 3293 // literal array (0) |
| 3294 frame_->EmitPush(tmp); | 3294 frame_->EmitPush(tmp); |
| 3295 // literal index (1) | 3295 // literal index (1) |
| 3296 frame_->EmitPush(Operand(Smi::FromInt(node->literal_index()))); | 3296 frame_->EmitPush(Operand(Smi::FromInt(node->literal_index()))); |
| 3297 // RegExp pattern (2) | 3297 // RegExp pattern (2) |
| 3298 frame_->EmitPush(Operand(node->pattern())); | 3298 frame_->EmitPush(Operand(node->pattern())); |
| 3299 // RegExp flags (3) | 3299 // RegExp flags (3) |
| 3300 frame_->EmitPush(Operand(node->flags())); | 3300 frame_->EmitPush(Operand(node->flags())); |
| 3301 frame_->CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); | 3301 frame_->CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); |
| 3302 __ Move(literal, r0); | 3302 __ Move(literal, r0); |
| 3303 | 3303 |
| 3304 // This call to bind will get us back to the virtual frame we had before | 3304 materialized.Bind(); |
| 3305 // where things are not spilled and the literal register is not on the stack. | 3305 |
| 3306 done.Bind(); | |
| 3307 // Push the literal. | |
| 3308 frame_->EmitPush(literal); | 3306 frame_->EmitPush(literal); |
| 3307 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; |
| 3308 frame_->EmitPush(Operand(Smi::FromInt(size))); |
| 3309 frame_->CallRuntime(Runtime::kAllocateInNewSpace, 1); |
| 3310 // TODO(lrn): Use AllocateInNewSpace macro with fallback to runtime. |
| 3311 // r0 is newly allocated space. |
| 3312 |
| 3313 // Reuse literal variable with (possibly) a new register, still holding |
| 3314 // the materialized boilerplate. |
| 3315 literal = frame_->PopToRegister(r0); |
| 3316 |
| 3317 __ CopyFields(r0, literal, tmp.bit(), size / kPointerSize); |
| 3318 |
| 3319 // Push the clone. |
| 3320 frame_->EmitPush(r0); |
| 3309 ASSERT_EQ(original_height + 1, frame_->height()); | 3321 ASSERT_EQ(original_height + 1, frame_->height()); |
| 3310 } | 3322 } |
| 3311 | 3323 |
| 3312 | 3324 |
| 3313 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) { | 3325 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) { |
| 3314 #ifdef DEBUG | 3326 #ifdef DEBUG |
| 3315 int original_height = frame_->height(); | 3327 int original_height = frame_->height(); |
| 3316 #endif | 3328 #endif |
| 3317 Comment cmnt(masm_, "[ ObjectLiteral"); | 3329 Comment cmnt(masm_, "[ ObjectLiteral"); |
| 3318 | 3330 |
| (...skipping 1998 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5317 // Load the two objects into registers and perform the comparison. | 5329 // Load the two objects into registers and perform the comparison. |
| 5318 Load(args->at(0)); | 5330 Load(args->at(0)); |
| 5319 Load(args->at(1)); | 5331 Load(args->at(1)); |
| 5320 Register lhs = frame_->PopToRegister(); | 5332 Register lhs = frame_->PopToRegister(); |
| 5321 Register rhs = frame_->PopToRegister(lhs); | 5333 Register rhs = frame_->PopToRegister(lhs); |
| 5322 __ cmp(lhs, rhs); | 5334 __ cmp(lhs, rhs); |
| 5323 cc_reg_ = eq; | 5335 cc_reg_ = eq; |
| 5324 } | 5336 } |
| 5325 | 5337 |
| 5326 | 5338 |
| 5339 void CodeGenerator::GenerateIsRegExpEquivalent(ZoneList<Expression*>* args) { |
| 5340 ASSERT(args->length() == 2); |
| 5341 |
| 5342 // Load the two objects into registers and perform the comparison. |
| 5343 Load(args->at(0)); |
| 5344 Load(args->at(1)); |
| 5345 Register right = frame_->PopToRegister(); |
| 5346 Register left = frame_->PopToRegister(right); |
| 5347 Register tmp = frame_->scratch0(); |
| 5348 Register tmp2 = frame_->scratch1(); |
| 5349 |
| 5350 // Jumps to done must have the eq flag set if the test is successful |
| 5351 // and clear if the test has failed. |
| 5352 Label done; |
| 5353 |
| 5354 // Fail if either is a non-HeapObject. |
| 5355 __ cmp(left, Operand(right)); |
| 5356 __ b(eq, &done); |
| 5357 __ and_(tmp, left, Operand(right)); |
| 5358 __ eor(tmp, tmp, Operand(kSmiTagMask)); |
| 5359 __ tst(tmp, Operand(kSmiTagMask)); |
| 5360 __ b(ne, &done); |
| 5361 __ ldr(tmp, FieldMemOperand(left, HeapObject::kMapOffset)); |
| 5362 __ ldrb(tmp2, FieldMemOperand(tmp, Map::kInstanceTypeOffset)); |
| 5363 __ cmp(tmp2, Operand(JS_REGEXP_TYPE)); |
| 5364 __ b(ne, &done); |
| 5365 __ ldr(tmp2, FieldMemOperand(right, HeapObject::kMapOffset)); |
| 5366 __ cmp(tmp, Operand(tmp2)); |
| 5367 __ b(ne, &done); |
| 5368 __ ldr(tmp, FieldMemOperand(left, JSRegExp::kDataOffset)); |
| 5369 __ ldr(tmp2, FieldMemOperand(right, JSRegExp::kDataOffset)); |
| 5370 __ cmp(tmp, tmp2); |
| 5371 __ bind(&done); |
| 5372 cc_reg_ = eq; |
| 5373 } |
| 5374 |
| 5375 |
| 5376 |
| 5327 void CodeGenerator::VisitCallRuntime(CallRuntime* node) { | 5377 void CodeGenerator::VisitCallRuntime(CallRuntime* node) { |
| 5328 #ifdef DEBUG | 5378 #ifdef DEBUG |
| 5329 int original_height = frame_->height(); | 5379 int original_height = frame_->height(); |
| 5330 #endif | 5380 #endif |
| 5331 if (CheckForInlineRuntimeCall(node)) { | 5381 if (CheckForInlineRuntimeCall(node)) { |
| 5332 ASSERT((has_cc() && frame_->height() == original_height) || | 5382 ASSERT((has_cc() && frame_->height() == original_height) || |
| 5333 (!has_cc() && frame_->height() == original_height + 1)); | 5383 (!has_cc() && frame_->height() == original_height + 1)); |
| 5334 return; | 5384 return; |
| 5335 } | 5385 } |
| 5336 | 5386 |
| (...skipping 1564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6901 } | 6951 } |
| 6902 | 6952 |
| 6903 if (length_ > 0) { | 6953 if (length_ > 0) { |
| 6904 // Get hold of the elements array of the boilerplate and setup the | 6954 // Get hold of the elements array of the boilerplate and setup the |
| 6905 // elements pointer in the resulting object. | 6955 // elements pointer in the resulting object. |
| 6906 __ ldr(r3, FieldMemOperand(r3, JSArray::kElementsOffset)); | 6956 __ ldr(r3, FieldMemOperand(r3, JSArray::kElementsOffset)); |
| 6907 __ add(r2, r0, Operand(JSArray::kSize)); | 6957 __ add(r2, r0, Operand(JSArray::kSize)); |
| 6908 __ str(r2, FieldMemOperand(r0, JSArray::kElementsOffset)); | 6958 __ str(r2, FieldMemOperand(r0, JSArray::kElementsOffset)); |
| 6909 | 6959 |
| 6910 // Copy the elements array. | 6960 // Copy the elements array. |
| 6911 for (int i = 0; i < elements_size; i += kPointerSize) { | 6961 __ CopyFields(r2, r3, r1.bit(), elements_size / kPointerSize); |
| 6912 __ ldr(r1, FieldMemOperand(r3, i)); | |
| 6913 __ str(r1, FieldMemOperand(r2, i)); | |
| 6914 } | |
| 6915 } | 6962 } |
| 6916 | 6963 |
| 6917 // Return and remove the on-stack parameters. | 6964 // Return and remove the on-stack parameters. |
| 6918 __ add(sp, sp, Operand(3 * kPointerSize)); | 6965 __ add(sp, sp, Operand(3 * kPointerSize)); |
| 6919 __ Ret(); | 6966 __ Ret(); |
| 6920 | 6967 |
| 6921 __ bind(&slow_case); | 6968 __ bind(&slow_case); |
| 6922 __ TailCallRuntime(Runtime::kCreateArrayLiteralShallow, 3, 1); | 6969 __ TailCallRuntime(Runtime::kCreateArrayLiteralShallow, 3, 1); |
| 6923 } | 6970 } |
| 6924 | 6971 |
| (...skipping 2848 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9773 &runtime, | 9820 &runtime, |
| 9774 static_cast<AllocationFlags>(TAG_OBJECT | SIZE_IN_WORDS)); | 9821 static_cast<AllocationFlags>(TAG_OBJECT | SIZE_IN_WORDS)); |
| 9775 | 9822 |
| 9776 // Get the arguments boilerplate from the current (global) context. | 9823 // Get the arguments boilerplate from the current (global) context. |
| 9777 int offset = Context::SlotOffset(Context::ARGUMENTS_BOILERPLATE_INDEX); | 9824 int offset = Context::SlotOffset(Context::ARGUMENTS_BOILERPLATE_INDEX); |
| 9778 __ ldr(r4, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); | 9825 __ ldr(r4, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); |
| 9779 __ ldr(r4, FieldMemOperand(r4, GlobalObject::kGlobalContextOffset)); | 9826 __ ldr(r4, FieldMemOperand(r4, GlobalObject::kGlobalContextOffset)); |
| 9780 __ ldr(r4, MemOperand(r4, offset)); | 9827 __ ldr(r4, MemOperand(r4, offset)); |
| 9781 | 9828 |
| 9782 // Copy the JS object part. | 9829 // Copy the JS object part. |
| 9783 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) { | 9830 __ CopyFields(r0, r4, r3.bit(), JSObject::kHeaderSize / kPointerSize); |
| 9784 __ ldr(r3, FieldMemOperand(r4, i)); | |
| 9785 __ str(r3, FieldMemOperand(r0, i)); | |
| 9786 } | |
| 9787 | 9831 |
| 9788 // Setup the callee in-object property. | 9832 // Setup the callee in-object property. |
| 9789 STATIC_ASSERT(Heap::arguments_callee_index == 0); | 9833 STATIC_ASSERT(Heap::arguments_callee_index == 0); |
| 9790 __ ldr(r3, MemOperand(sp, 2 * kPointerSize)); | 9834 __ ldr(r3, MemOperand(sp, 2 * kPointerSize)); |
| 9791 __ str(r3, FieldMemOperand(r0, JSObject::kHeaderSize)); | 9835 __ str(r3, FieldMemOperand(r0, JSObject::kHeaderSize)); |
| 9792 | 9836 |
| 9793 // Get the length (smi tagged) and set that as an in-object property too. | 9837 // Get the length (smi tagged) and set that as an in-object property too. |
| 9794 STATIC_ASSERT(Heap::arguments_length_index == 1); | 9838 STATIC_ASSERT(Heap::arguments_length_index == 1); |
| 9795 __ ldr(r1, MemOperand(sp, 0 * kPointerSize)); | 9839 __ ldr(r1, MemOperand(sp, 0 * kPointerSize)); |
| 9796 __ str(r1, FieldMemOperand(r0, JSObject::kHeaderSize + kPointerSize)); | 9840 __ str(r1, FieldMemOperand(r0, JSObject::kHeaderSize + kPointerSize)); |
| (...skipping 1593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11390 __ bind(&string_add_runtime); | 11434 __ bind(&string_add_runtime); |
| 11391 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); | 11435 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); |
| 11392 } | 11436 } |
| 11393 | 11437 |
| 11394 | 11438 |
| 11395 #undef __ | 11439 #undef __ |
| 11396 | 11440 |
| 11397 } } // namespace v8::internal | 11441 } } // namespace v8::internal |
| 11398 | 11442 |
| 11399 #endif // V8_TARGET_ARCH_ARM | 11443 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |