| 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 |