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 global context. | 1309 // Terminate at native context. |
1310 __ ldr(temp, FieldMemOperand(next, HeapObject::kMapOffset)); | 1310 __ ldr(temp, FieldMemOperand(next, HeapObject::kMapOffset)); |
1311 __ LoadRoot(ip, Heap::kGlobalContextMapRootIndex); | 1311 __ LoadRoot(ip, Heap::kNativeContextMapRootIndex); |
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 1430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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_INDEX)); | 2761 __ ldr(r3, ContextOperand(cp, Context::GLOBAL_INDEX)); |
2762 __ ldr(r3, FieldMemOperand(r3, GlobalObject::kGlobalContextOffset)); | 2762 __ ldr(r3, FieldMemOperand(r3, GlobalObject::kNativeContextOffset)); |
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 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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, ContextOperand(context_register(), Context::GLOBAL_INDEX)); | 3041 __ ldr(r0, ContextOperand(context_register(), Context::GLOBAL_INDEX)); |
3042 __ ldr(r0, FieldMemOperand(r0, GlobalObject::kGlobalContextOffset)); | 3042 __ ldr(r0, FieldMemOperand(r0, GlobalObject::kNativeContextOffset)); |
3043 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); | 3043 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); |
3044 | 3044 |
3045 CpuFeatures::Scope scope(VFP2); | 3045 CpuFeatures::Scope scope(VFP2); |
3046 // 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. |
3047 // Create this constant using mov/orr to avoid PC relative load. | 3047 // Create this constant using mov/orr to avoid PC relative load. |
3048 __ mov(r1, Operand(0x41000000)); | 3048 __ mov(r1, Operand(0x41000000)); |
3049 __ orr(r1, r1, Operand(0x300000)); | 3049 __ orr(r1, r1, Operand(0x300000)); |
3050 // Move 0x41300000xxxxxxxx (x = random bits) to VFP. | 3050 // Move 0x41300000xxxxxxxx (x = random bits) to VFP. |
3051 __ vmov(d7, r0, r1); | 3051 __ vmov(d7, r0, r1); |
3052 // Move 0x4130000000000000 to VFP. | 3052 // Move 0x4130000000000000 to VFP. |
3053 __ mov(r0, Operand(0, RelocInfo::NONE)); | 3053 __ mov(r0, Operand(0, RelocInfo::NONE)); |
3054 __ vmov(d8, r0, r1); | 3054 __ vmov(d8, r0, r1); |
3055 // Subtract and store the result in the heap number. | 3055 // Subtract and store the result in the heap number. |
3056 __ vsub(d7, d7, d8); | 3056 __ vsub(d7, d7, d8); |
3057 __ sub(r0, r4, Operand(kHeapObjectTag)); | 3057 __ sub(r0, r4, Operand(kHeapObjectTag)); |
3058 __ vstr(d7, r0, HeapNumber::kValueOffset); | 3058 __ vstr(d7, r0, HeapNumber::kValueOffset); |
3059 __ mov(r0, r4); | 3059 __ mov(r0, r4); |
3060 } else { | 3060 } else { |
3061 __ PrepareCallCFunction(2, r0); | 3061 __ PrepareCallCFunction(2, r0); |
3062 __ ldr(r1, ContextOperand(context_register(), Context::GLOBAL_INDEX)); | 3062 __ ldr(r1, ContextOperand(context_register(), Context::GLOBAL_INDEX)); |
3063 __ mov(r0, Operand(r4)); | 3063 __ mov(r0, Operand(r4)); |
3064 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalContextOffset)); | 3064 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kNativeContextOffset)); |
3065 __ CallCFunction( | 3065 __ CallCFunction( |
3066 ExternalReference::fill_heap_number_with_random_function(isolate()), 2); | 3066 ExternalReference::fill_heap_number_with_random_function(isolate()), 2); |
3067 } | 3067 } |
3068 | 3068 |
3069 context()->Plug(r0); | 3069 context()->Plug(r0); |
3070 } | 3070 } |
3071 | 3071 |
3072 | 3072 |
3073 void FullCodeGenerator::EmitSubString(CallRuntime* expr) { | 3073 void FullCodeGenerator::EmitSubString(CallRuntime* expr) { |
3074 // 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... |
3452 } | 3452 } |
3453 | 3453 |
3454 | 3454 |
3455 void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) { | 3455 void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) { |
3456 ZoneList<Expression*>* args = expr->arguments(); | 3456 ZoneList<Expression*>* args = expr->arguments(); |
3457 ASSERT_EQ(2, args->length()); | 3457 ASSERT_EQ(2, args->length()); |
3458 ASSERT_NE(NULL, args->at(0)->AsLiteral()); | 3458 ASSERT_NE(NULL, args->at(0)->AsLiteral()); |
3459 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); | 3459 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); |
3460 | 3460 |
3461 Handle<FixedArray> jsfunction_result_caches( | 3461 Handle<FixedArray> jsfunction_result_caches( |
3462 isolate()->global_context()->jsfunction_result_caches()); | 3462 isolate()->native_context()->jsfunction_result_caches()); |
3463 if (jsfunction_result_caches->length() <= cache_id) { | 3463 if (jsfunction_result_caches->length() <= cache_id) { |
3464 __ Abort("Attempt to use undefined cache."); | 3464 __ Abort("Attempt to use undefined cache."); |
3465 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); | 3465 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); |
3466 context()->Plug(r0); | 3466 context()->Plug(r0); |
3467 return; | 3467 return; |
3468 } | 3468 } |
3469 | 3469 |
3470 VisitForAccumulatorValue(args->at(1)); | 3470 VisitForAccumulatorValue(args->at(1)); |
3471 | 3471 |
3472 Register key = r0; | 3472 Register key = r0; |
3473 Register cache = r1; | 3473 Register cache = r1; |
3474 __ ldr(cache, ContextOperand(cp, Context::GLOBAL_INDEX)); | 3474 __ ldr(cache, ContextOperand(cp, Context::GLOBAL_INDEX)); |
3475 __ ldr(cache, FieldMemOperand(cache, GlobalObject::kGlobalContextOffset)); | 3475 __ ldr(cache, FieldMemOperand(cache, GlobalObject::kNativeContextOffset)); |
3476 __ ldr(cache, ContextOperand(cache, Context::JSFUNCTION_RESULT_CACHES_INDEX)); | 3476 __ ldr(cache, ContextOperand(cache, Context::JSFUNCTION_RESULT_CACHES_INDEX)); |
3477 __ ldr(cache, | 3477 __ ldr(cache, |
3478 FieldMemOperand(cache, FixedArray::OffsetOfElementAt(cache_id))); | 3478 FieldMemOperand(cache, FixedArray::OffsetOfElementAt(cache_id))); |
3479 | 3479 |
3480 | 3480 |
3481 Label done, not_found; | 3481 Label done, not_found; |
3482 // tmp now holds finger offset as a smi. | 3482 // tmp now holds finger offset as a smi. |
3483 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1); | 3483 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1); |
3484 __ ldr(r2, FieldMemOperand(cache, JSFunctionResultCache::kFingerOffset)); | 3484 __ ldr(r2, FieldMemOperand(cache, JSFunctionResultCache::kFingerOffset)); |
3485 // 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... |
4443 | 4443 |
4444 void FullCodeGenerator::LoadContextField(Register dst, int context_index) { | 4444 void FullCodeGenerator::LoadContextField(Register dst, int context_index) { |
4445 __ ldr(dst, ContextOperand(cp, context_index)); | 4445 __ ldr(dst, ContextOperand(cp, context_index)); |
4446 } | 4446 } |
4447 | 4447 |
4448 | 4448 |
4449 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() { | 4449 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() { |
4450 Scope* declaration_scope = scope()->DeclarationScope(); | 4450 Scope* declaration_scope = scope()->DeclarationScope(); |
4451 if (declaration_scope->is_global_scope() || | 4451 if (declaration_scope->is_global_scope() || |
4452 declaration_scope->is_module_scope()) { | 4452 declaration_scope->is_module_scope()) { |
4453 // Contexts nested in the global context have a canonical empty function | 4453 // Contexts nested in the native context have a canonical empty function |
4454 // as their closure, not the anonymous closure containing the global | 4454 // as their closure, not the anonymous closure containing the global |
4455 // 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 |
4456 // function. | 4456 // function. |
4457 __ mov(ip, Operand(Smi::FromInt(0))); | 4457 __ mov(ip, Operand(Smi::FromInt(0))); |
4458 } else if (declaration_scope->is_eval_scope()) { | 4458 } else if (declaration_scope->is_eval_scope()) { |
4459 // 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 |
4460 // context calling eval, not the anonymous closure containing the eval | 4460 // context calling eval, not the anonymous closure containing the eval |
4461 // code. Fetch it from the context. | 4461 // code. Fetch it from the context. |
4462 __ ldr(ip, ContextOperand(cp, Context::CLOSURE_INDEX)); | 4462 __ ldr(ip, ContextOperand(cp, Context::CLOSURE_INDEX)); |
4463 } else { | 4463 } else { |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4565 *context_length = 0; | 4565 *context_length = 0; |
4566 return previous_; | 4566 return previous_; |
4567 } | 4567 } |
4568 | 4568 |
4569 | 4569 |
4570 #undef __ | 4570 #undef __ |
4571 | 4571 |
4572 } } // namespace v8::internal | 4572 } } // namespace v8::internal |
4573 | 4573 |
4574 #endif // V8_TARGET_ARCH_ARM | 4574 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |