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 |