OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 1288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1299 if (!s->outer_scope_calls_non_strict_eval() || s->is_eval_scope()) break; | 1299 if (!s->outer_scope_calls_non_strict_eval() || s->is_eval_scope()) break; |
1300 s = s->outer_scope(); | 1300 s = s->outer_scope(); |
1301 } | 1301 } |
1302 | 1302 |
1303 if (s->is_eval_scope()) { | 1303 if (s->is_eval_scope()) { |
1304 Label loop, fast; | 1304 Label loop, fast; |
1305 if (!current.is(next)) { | 1305 if (!current.is(next)) { |
1306 __ Move(next, current); | 1306 __ Move(next, current); |
1307 } | 1307 } |
1308 __ bind(&loop); | 1308 __ bind(&loop); |
1309 // Terminate at native context. | 1309 // Terminate at global context. |
1310 __ ldr(temp, FieldMemOperand(next, HeapObject::kMapOffset)); | 1310 __ ldr(temp, FieldMemOperand(next, HeapObject::kMapOffset)); |
1311 __ LoadRoot(ip, Heap::kNativeContextMapRootIndex); | 1311 __ LoadRoot(ip, Heap::kGlobalContextMapRootIndex); |
1312 __ cmp(temp, ip); | 1312 __ cmp(temp, ip); |
1313 __ b(eq, &fast); | 1313 __ b(eq, &fast); |
1314 // Check that extension is NULL. | 1314 // Check that extension is NULL. |
1315 __ ldr(temp, ContextOperand(next, Context::EXTENSION_INDEX)); | 1315 __ ldr(temp, ContextOperand(next, Context::EXTENSION_INDEX)); |
1316 __ tst(temp, temp); | 1316 __ tst(temp, temp); |
1317 __ b(ne, slow); | 1317 __ b(ne, slow); |
1318 // Load next context in chain. | 1318 // Load next context in chain. |
1319 __ ldr(next, ContextOperand(next, Context::PREVIOUS_INDEX)); | 1319 __ ldr(next, ContextOperand(next, Context::PREVIOUS_INDEX)); |
1320 __ b(&loop); | 1320 __ b(&loop); |
1321 __ bind(&fast); | 1321 __ bind(&fast); |
(...skipping 1429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2751 __ add(r4, r4, Operand(kPointerSize)); | 2751 __ add(r4, r4, Operand(kPointerSize)); |
2752 __ bind(&entry); | 2752 __ bind(&entry); |
2753 __ cmp(r4, Operand(r2)); | 2753 __ cmp(r4, Operand(r2)); |
2754 __ b(ne, &loop); | 2754 __ b(ne, &loop); |
2755 | 2755 |
2756 // If a valueOf property is not found on the object check that it's | 2756 // If a valueOf property is not found on the object check that it's |
2757 // prototype is the un-modified String prototype. If not result is false. | 2757 // prototype is the un-modified String prototype. If not result is false. |
2758 __ ldr(r2, FieldMemOperand(r1, Map::kPrototypeOffset)); | 2758 __ ldr(r2, FieldMemOperand(r1, Map::kPrototypeOffset)); |
2759 __ JumpIfSmi(r2, if_false); | 2759 __ JumpIfSmi(r2, if_false); |
2760 __ ldr(r2, FieldMemOperand(r2, HeapObject::kMapOffset)); | 2760 __ ldr(r2, FieldMemOperand(r2, HeapObject::kMapOffset)); |
2761 __ ldr(r3, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); | 2761 __ ldr(r3, ContextOperand(cp, Context::GLOBAL_INDEX)); |
2762 __ ldr(r3, FieldMemOperand(r3, GlobalObject::kNativeContextOffset)); | 2762 __ ldr(r3, FieldMemOperand(r3, GlobalObject::kGlobalContextOffset)); |
2763 __ ldr(r3, ContextOperand(r3, Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX)); | 2763 __ ldr(r3, ContextOperand(r3, Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX)); |
2764 __ cmp(r2, r3); | 2764 __ cmp(r2, r3); |
2765 __ b(ne, if_false); | 2765 __ b(ne, if_false); |
2766 | 2766 |
2767 // Set the bit in the map to indicate that it has been checked safe for | 2767 // Set the bit in the map to indicate that it has been checked safe for |
2768 // default valueOf and set true result. | 2768 // default valueOf and set true result. |
2769 __ ldrb(r2, FieldMemOperand(r1, Map::kBitField2Offset)); | 2769 __ ldrb(r2, FieldMemOperand(r1, Map::kBitField2Offset)); |
2770 __ orr(r2, r2, Operand(1 << Map::kStringWrapperSafeForDefaultValueOf)); | 2770 __ orr(r2, r2, Operand(1 << Map::kStringWrapperSafeForDefaultValueOf)); |
2771 __ strb(r2, FieldMemOperand(r1, Map::kBitField2Offset)); | 2771 __ strb(r2, FieldMemOperand(r1, Map::kBitField2Offset)); |
2772 __ jmp(if_true); | 2772 __ jmp(if_true); |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3031 __ CallRuntime(Runtime::kNumberAlloc, 0); | 3031 __ CallRuntime(Runtime::kNumberAlloc, 0); |
3032 __ mov(r4, Operand(r0)); | 3032 __ mov(r4, Operand(r0)); |
3033 | 3033 |
3034 __ bind(&heapnumber_allocated); | 3034 __ bind(&heapnumber_allocated); |
3035 | 3035 |
3036 // Convert 32 random bits in r0 to 0.(32 random bits) in a double | 3036 // Convert 32 random bits in r0 to 0.(32 random bits) in a double |
3037 // by computing: | 3037 // by computing: |
3038 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). | 3038 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). |
3039 if (CpuFeatures::IsSupported(VFP2)) { | 3039 if (CpuFeatures::IsSupported(VFP2)) { |
3040 __ PrepareCallCFunction(1, r0); | 3040 __ PrepareCallCFunction(1, r0); |
3041 __ ldr(r0, | 3041 __ ldr(r0, ContextOperand(context_register(), Context::GLOBAL_INDEX)); |
3042 ContextOperand(context_register(), Context::GLOBAL_OBJECT_INDEX)); | 3042 __ ldr(r0, FieldMemOperand(r0, GlobalObject::kGlobalContextOffset)); |
3043 __ ldr(r0, FieldMemOperand(r0, GlobalObject::kNativeContextOffset)); | |
3044 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); | 3043 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); |
3045 | 3044 |
3046 CpuFeatures::Scope scope(VFP2); | 3045 CpuFeatures::Scope scope(VFP2); |
3047 // 0x41300000 is the top half of 1.0 x 2^20 as a double. | 3046 // 0x41300000 is the top half of 1.0 x 2^20 as a double. |
3048 // Create this constant using mov/orr to avoid PC relative load. | 3047 // Create this constant using mov/orr to avoid PC relative load. |
3049 __ mov(r1, Operand(0x41000000)); | 3048 __ mov(r1, Operand(0x41000000)); |
3050 __ orr(r1, r1, Operand(0x300000)); | 3049 __ orr(r1, r1, Operand(0x300000)); |
3051 // Move 0x41300000xxxxxxxx (x = random bits) to VFP. | 3050 // Move 0x41300000xxxxxxxx (x = random bits) to VFP. |
3052 __ vmov(d7, r0, r1); | 3051 __ vmov(d7, r0, r1); |
3053 // Move 0x4130000000000000 to VFP. | 3052 // Move 0x4130000000000000 to VFP. |
3054 __ mov(r0, Operand(0, RelocInfo::NONE)); | 3053 __ mov(r0, Operand(0, RelocInfo::NONE)); |
3055 __ vmov(d8, r0, r1); | 3054 __ vmov(d8, r0, r1); |
3056 // Subtract and store the result in the heap number. | 3055 // Subtract and store the result in the heap number. |
3057 __ vsub(d7, d7, d8); | 3056 __ vsub(d7, d7, d8); |
3058 __ sub(r0, r4, Operand(kHeapObjectTag)); | 3057 __ sub(r0, r4, Operand(kHeapObjectTag)); |
3059 __ vstr(d7, r0, HeapNumber::kValueOffset); | 3058 __ vstr(d7, r0, HeapNumber::kValueOffset); |
3060 __ mov(r0, r4); | 3059 __ mov(r0, r4); |
3061 } else { | 3060 } else { |
3062 __ PrepareCallCFunction(2, r0); | 3061 __ PrepareCallCFunction(2, r0); |
3063 __ ldr(r1, | 3062 __ ldr(r1, ContextOperand(context_register(), Context::GLOBAL_INDEX)); |
3064 ContextOperand(context_register(), Context::GLOBAL_OBJECT_INDEX)); | |
3065 __ mov(r0, Operand(r4)); | 3063 __ mov(r0, Operand(r4)); |
3066 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kNativeContextOffset)); | 3064 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalContextOffset)); |
3067 __ CallCFunction( | 3065 __ CallCFunction( |
3068 ExternalReference::fill_heap_number_with_random_function(isolate()), 2); | 3066 ExternalReference::fill_heap_number_with_random_function(isolate()), 2); |
3069 } | 3067 } |
3070 | 3068 |
3071 context()->Plug(r0); | 3069 context()->Plug(r0); |
3072 } | 3070 } |
3073 | 3071 |
3074 | 3072 |
3075 void FullCodeGenerator::EmitSubString(CallRuntime* expr) { | 3073 void FullCodeGenerator::EmitSubString(CallRuntime* expr) { |
3076 // Load the arguments on the stack and call the stub. | 3074 // Load the arguments on the stack and call the stub. |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3454 } | 3452 } |
3455 | 3453 |
3456 | 3454 |
3457 void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) { | 3455 void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) { |
3458 ZoneList<Expression*>* args = expr->arguments(); | 3456 ZoneList<Expression*>* args = expr->arguments(); |
3459 ASSERT_EQ(2, args->length()); | 3457 ASSERT_EQ(2, args->length()); |
3460 ASSERT_NE(NULL, args->at(0)->AsLiteral()); | 3458 ASSERT_NE(NULL, args->at(0)->AsLiteral()); |
3461 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); | 3459 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); |
3462 | 3460 |
3463 Handle<FixedArray> jsfunction_result_caches( | 3461 Handle<FixedArray> jsfunction_result_caches( |
3464 isolate()->native_context()->jsfunction_result_caches()); | 3462 isolate()->global_context()->jsfunction_result_caches()); |
3465 if (jsfunction_result_caches->length() <= cache_id) { | 3463 if (jsfunction_result_caches->length() <= cache_id) { |
3466 __ Abort("Attempt to use undefined cache."); | 3464 __ Abort("Attempt to use undefined cache."); |
3467 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); | 3465 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); |
3468 context()->Plug(r0); | 3466 context()->Plug(r0); |
3469 return; | 3467 return; |
3470 } | 3468 } |
3471 | 3469 |
3472 VisitForAccumulatorValue(args->at(1)); | 3470 VisitForAccumulatorValue(args->at(1)); |
3473 | 3471 |
3474 Register key = r0; | 3472 Register key = r0; |
3475 Register cache = r1; | 3473 Register cache = r1; |
3476 __ ldr(cache, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); | 3474 __ ldr(cache, ContextOperand(cp, Context::GLOBAL_INDEX)); |
3477 __ ldr(cache, FieldMemOperand(cache, GlobalObject::kNativeContextOffset)); | 3475 __ ldr(cache, FieldMemOperand(cache, GlobalObject::kGlobalContextOffset)); |
3478 __ ldr(cache, ContextOperand(cache, Context::JSFUNCTION_RESULT_CACHES_INDEX)); | 3476 __ ldr(cache, ContextOperand(cache, Context::JSFUNCTION_RESULT_CACHES_INDEX)); |
3479 __ ldr(cache, | 3477 __ ldr(cache, |
3480 FieldMemOperand(cache, FixedArray::OffsetOfElementAt(cache_id))); | 3478 FieldMemOperand(cache, FixedArray::OffsetOfElementAt(cache_id))); |
3481 | 3479 |
3482 | 3480 |
3483 Label done, not_found; | 3481 Label done, not_found; |
3484 // tmp now holds finger offset as a smi. | 3482 // tmp now holds finger offset as a smi. |
3485 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1); | 3483 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1); |
3486 __ ldr(r2, FieldMemOperand(cache, JSFunctionResultCache::kFingerOffset)); | 3484 __ ldr(r2, FieldMemOperand(cache, JSFunctionResultCache::kFingerOffset)); |
3487 // r2 now holds finger offset as a smi. | 3485 // r2 now holds finger offset as a smi. |
(...skipping 957 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4445 | 4443 |
4446 void FullCodeGenerator::LoadContextField(Register dst, int context_index) { | 4444 void FullCodeGenerator::LoadContextField(Register dst, int context_index) { |
4447 __ ldr(dst, ContextOperand(cp, context_index)); | 4445 __ ldr(dst, ContextOperand(cp, context_index)); |
4448 } | 4446 } |
4449 | 4447 |
4450 | 4448 |
4451 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() { | 4449 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() { |
4452 Scope* declaration_scope = scope()->DeclarationScope(); | 4450 Scope* declaration_scope = scope()->DeclarationScope(); |
4453 if (declaration_scope->is_global_scope() || | 4451 if (declaration_scope->is_global_scope() || |
4454 declaration_scope->is_module_scope()) { | 4452 declaration_scope->is_module_scope()) { |
4455 // Contexts nested in the native context have a canonical empty function | 4453 // Contexts nested in the global context have a canonical empty function |
4456 // as their closure, not the anonymous closure containing the global | 4454 // as their closure, not the anonymous closure containing the global |
4457 // code. Pass a smi sentinel and let the runtime look up the empty | 4455 // code. Pass a smi sentinel and let the runtime look up the empty |
4458 // function. | 4456 // function. |
4459 __ mov(ip, Operand(Smi::FromInt(0))); | 4457 __ mov(ip, Operand(Smi::FromInt(0))); |
4460 } else if (declaration_scope->is_eval_scope()) { | 4458 } else if (declaration_scope->is_eval_scope()) { |
4461 // Contexts created by a call to eval have the same closure as the | 4459 // Contexts created by a call to eval have the same closure as the |
4462 // context calling eval, not the anonymous closure containing the eval | 4460 // context calling eval, not the anonymous closure containing the eval |
4463 // code. Fetch it from the context. | 4461 // code. Fetch it from the context. |
4464 __ ldr(ip, ContextOperand(cp, Context::CLOSURE_INDEX)); | 4462 __ ldr(ip, ContextOperand(cp, Context::CLOSURE_INDEX)); |
4465 } else { | 4463 } else { |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4567 *context_length = 0; | 4565 *context_length = 0; |
4568 return previous_; | 4566 return previous_; |
4569 } | 4567 } |
4570 | 4568 |
4571 | 4569 |
4572 #undef __ | 4570 #undef __ |
4573 | 4571 |
4574 } } // namespace v8::internal | 4572 } } // namespace v8::internal |
4575 | 4573 |
4576 #endif // V8_TARGET_ARCH_ARM | 4574 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |