OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 1462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1473 __ b(ne, miss); | 1473 __ b(ne, miss); |
1474 } else { | 1474 } else { |
1475 __ cmp(r1, Operand(Handle<JSFunction>(function))); | 1475 __ cmp(r1, Operand(Handle<JSFunction>(function))); |
1476 __ b(ne, miss); | 1476 __ b(ne, miss); |
1477 } | 1477 } |
1478 } | 1478 } |
1479 | 1479 |
1480 | 1480 |
1481 MaybeObject* CallStubCompiler::GenerateMissBranch() { | 1481 MaybeObject* CallStubCompiler::GenerateMissBranch() { |
1482 MaybeObject* maybe_obj = | 1482 MaybeObject* maybe_obj = |
1483 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), | 1483 isolate()->stub_cache()->TryComputeCallMiss(arguments().immediate(), |
1484 kind_, | 1484 kind_, |
1485 extra_ic_state_); | 1485 extra_state_); |
1486 Object* obj; | 1486 Object* obj; |
1487 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1487 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
1488 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); | 1488 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); |
1489 return obj; | 1489 return obj; |
1490 } | 1490 } |
1491 | 1491 |
1492 | 1492 |
1493 MaybeObject* CallStubCompiler::CompileCallField(JSObject* object, | 1493 MaybeObject* CallStubCompiler::CompileCallField(JSObject* object, |
1494 JSObject* holder, | 1494 JSObject* holder, |
1495 int index, | 1495 int index, |
(...skipping 10 matching lines...) Expand all Loading... |
1506 | 1506 |
1507 // Get the receiver of the function from the stack into r0. | 1507 // Get the receiver of the function from the stack into r0. |
1508 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); | 1508 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); |
1509 // Check that the receiver isn't a smi. | 1509 // Check that the receiver isn't a smi. |
1510 __ JumpIfSmi(r0, &miss); | 1510 __ JumpIfSmi(r0, &miss); |
1511 | 1511 |
1512 // Do the right check and compute the holder register. | 1512 // Do the right check and compute the holder register. |
1513 Register reg = CheckPrototypes(object, r0, holder, r1, r3, r4, name, &miss); | 1513 Register reg = CheckPrototypes(object, r0, holder, r1, r3, r4, name, &miss); |
1514 GenerateFastPropertyLoad(masm(), r1, reg, holder, index); | 1514 GenerateFastPropertyLoad(masm(), r1, reg, holder, index); |
1515 | 1515 |
1516 GenerateCallFunction(masm(), object, arguments(), &miss, extra_ic_state_); | 1516 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); |
1517 | 1517 |
1518 // Handle call cache miss. | 1518 // Handle call cache miss. |
1519 __ bind(&miss); | 1519 __ bind(&miss); |
1520 MaybeObject* maybe_result = GenerateMissBranch(); | 1520 MaybeObject* maybe_result = GenerateMissBranch(); |
1521 if (maybe_result->IsFailure()) return maybe_result; | 1521 if (maybe_result->IsFailure()) return maybe_result; |
1522 | 1522 |
1523 // Return the generated code. | 1523 // Return the generated code. |
1524 return GetCode(FIELD, name); | 1524 return GetCode(FIELD, name); |
1525 } | 1525 } |
1526 | 1526 |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1824 if (!object->IsString() || cell != NULL) return heap()->undefined_value(); | 1824 if (!object->IsString() || cell != NULL) return heap()->undefined_value(); |
1825 | 1825 |
1826 const int argc = arguments().immediate(); | 1826 const int argc = arguments().immediate(); |
1827 | 1827 |
1828 Label miss; | 1828 Label miss; |
1829 Label name_miss; | 1829 Label name_miss; |
1830 Label index_out_of_range; | 1830 Label index_out_of_range; |
1831 Label* index_out_of_range_label = &index_out_of_range; | 1831 Label* index_out_of_range_label = &index_out_of_range; |
1832 | 1832 |
1833 if (kind_ == Code::CALL_IC && | 1833 if (kind_ == Code::CALL_IC && |
1834 (CallICBase::StringStubState::decode(extra_ic_state_) == | 1834 (CallICBase::StringStubState::decode(extra_state_) == |
1835 DEFAULT_STRING_STUB)) { | 1835 DEFAULT_STRING_STUB)) { |
1836 index_out_of_range_label = &miss; | 1836 index_out_of_range_label = &miss; |
1837 } | 1837 } |
1838 | 1838 |
1839 GenerateNameCheck(name, &name_miss); | 1839 GenerateNameCheck(name, &name_miss); |
1840 | 1840 |
1841 // Check that the maps starting from the prototype haven't changed. | 1841 // Check that the maps starting from the prototype haven't changed. |
1842 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 1842 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
1843 Context::STRING_FUNCTION_INDEX, | 1843 Context::STRING_FUNCTION_INDEX, |
1844 r0, | 1844 r0, |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1910 if (!object->IsString() || cell != NULL) return heap()->undefined_value(); | 1910 if (!object->IsString() || cell != NULL) return heap()->undefined_value(); |
1911 | 1911 |
1912 const int argc = arguments().immediate(); | 1912 const int argc = arguments().immediate(); |
1913 | 1913 |
1914 Label miss; | 1914 Label miss; |
1915 Label name_miss; | 1915 Label name_miss; |
1916 Label index_out_of_range; | 1916 Label index_out_of_range; |
1917 Label* index_out_of_range_label = &index_out_of_range; | 1917 Label* index_out_of_range_label = &index_out_of_range; |
1918 | 1918 |
1919 if (kind_ == Code::CALL_IC && | 1919 if (kind_ == Code::CALL_IC && |
1920 (CallICBase::StringStubState::decode(extra_ic_state_) == | 1920 (CallICBase::StringStubState::decode(extra_state_) == |
1921 DEFAULT_STRING_STUB)) { | 1921 DEFAULT_STRING_STUB)) { |
1922 index_out_of_range_label = &miss; | 1922 index_out_of_range_label = &miss; |
1923 } | 1923 } |
1924 | 1924 |
1925 GenerateNameCheck(name, &name_miss); | 1925 GenerateNameCheck(name, &name_miss); |
1926 | 1926 |
1927 // Check that the maps starting from the prototype haven't changed. | 1927 // Check that the maps starting from the prototype haven't changed. |
1928 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 1928 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
1929 Context::STRING_FUNCTION_INDEX, | 1929 Context::STRING_FUNCTION_INDEX, |
1930 r0, | 1930 r0, |
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2467 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, r3, | 2467 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, r3, |
2468 r1, r4, name, &miss); | 2468 r1, r4, name, &miss); |
2469 } | 2469 } |
2470 break; | 2470 break; |
2471 } | 2471 } |
2472 | 2472 |
2473 default: | 2473 default: |
2474 UNREACHABLE(); | 2474 UNREACHABLE(); |
2475 } | 2475 } |
2476 | 2476 |
2477 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | 2477 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
2478 ? CALL_AS_FUNCTION | 2478 ? CALL_AS_FUNCTION |
2479 : CALL_AS_METHOD; | 2479 : CALL_AS_METHOD; |
2480 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, call_kind); | 2480 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, call_kind); |
2481 | 2481 |
2482 // Handle call cache miss. | 2482 // Handle call cache miss. |
2483 __ bind(&miss); | 2483 __ bind(&miss); |
2484 MaybeObject* maybe_result = GenerateMissBranch(); | 2484 MaybeObject* maybe_result = GenerateMissBranch(); |
2485 if (maybe_result->IsFailure()) return maybe_result; | 2485 if (maybe_result->IsFailure()) return maybe_result; |
2486 | 2486 |
2487 // Return the generated code. | 2487 // Return the generated code. |
(...skipping 15 matching lines...) Expand all Loading... |
2503 | 2503 |
2504 // Get the number of arguments. | 2504 // Get the number of arguments. |
2505 const int argc = arguments().immediate(); | 2505 const int argc = arguments().immediate(); |
2506 | 2506 |
2507 LookupResult lookup(isolate()); | 2507 LookupResult lookup(isolate()); |
2508 LookupPostInterceptor(holder, name, &lookup); | 2508 LookupPostInterceptor(holder, name, &lookup); |
2509 | 2509 |
2510 // Get the receiver from the stack. | 2510 // Get the receiver from the stack. |
2511 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 2511 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
2512 | 2512 |
2513 CallInterceptorCompiler compiler(this, arguments(), r2, extra_ic_state_); | 2513 CallInterceptorCompiler compiler(this, arguments(), r2, extra_state_); |
2514 MaybeObject* result = compiler.Compile(masm(), | 2514 MaybeObject* result = compiler.Compile(masm(), |
2515 object, | 2515 object, |
2516 holder, | 2516 holder, |
2517 name, | 2517 name, |
2518 &lookup, | 2518 &lookup, |
2519 r1, | 2519 r1, |
2520 r3, | 2520 r3, |
2521 r4, | 2521 r4, |
2522 r0, | 2522 r0, |
2523 &miss); | 2523 &miss); |
2524 if (result->IsFailure()) { | 2524 if (result->IsFailure()) { |
2525 return result; | 2525 return result; |
2526 } | 2526 } |
2527 | 2527 |
2528 // Move returned value, the function to call, to r1. | 2528 // Move returned value, the function to call, to r1. |
2529 __ mov(r1, r0); | 2529 __ mov(r1, r0); |
2530 // Restore receiver. | 2530 // Restore receiver. |
2531 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); | 2531 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); |
2532 | 2532 |
2533 GenerateCallFunction(masm(), object, arguments(), &miss, extra_ic_state_); | 2533 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); |
2534 | 2534 |
2535 // Handle call cache miss. | 2535 // Handle call cache miss. |
2536 __ bind(&miss); | 2536 __ bind(&miss); |
2537 MaybeObject* maybe_result = GenerateMissBranch(); | 2537 MaybeObject* maybe_result = GenerateMissBranch(); |
2538 if (maybe_result->IsFailure()) return maybe_result; | 2538 if (maybe_result->IsFailure()) return maybe_result; |
2539 | 2539 |
2540 // Return the generated code. | 2540 // Return the generated code. |
2541 return GetCode(INTERCEPTOR, name); | 2541 return GetCode(INTERCEPTOR, name); |
2542 } | 2542 } |
2543 | 2543 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2578 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset)); | 2578 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset)); |
2579 __ str(r3, MemOperand(sp, argc * kPointerSize)); | 2579 __ str(r3, MemOperand(sp, argc * kPointerSize)); |
2580 } | 2580 } |
2581 | 2581 |
2582 // Setup the context (function already in r1). | 2582 // Setup the context (function already in r1). |
2583 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); | 2583 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); |
2584 | 2584 |
2585 // Jump to the cached code (tail call). | 2585 // Jump to the cached code (tail call). |
2586 Counters* counters = masm()->isolate()->counters(); | 2586 Counters* counters = masm()->isolate()->counters(); |
2587 __ IncrementCounter(counters->call_global_inline(), 1, r3, r4); | 2587 __ IncrementCounter(counters->call_global_inline(), 1, r3, r4); |
2588 ASSERT(function->is_compiled()); | |
2589 Handle<Code> code(function->code()); | 2588 Handle<Code> code(function->code()); |
2590 ParameterCount expected(function->shared()->formal_parameter_count()); | 2589 ParameterCount expected(function->shared()->formal_parameter_count()); |
2591 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | 2590 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
2592 ? CALL_AS_FUNCTION | 2591 ? CALL_AS_FUNCTION |
2593 : CALL_AS_METHOD; | 2592 : CALL_AS_METHOD; |
2594 if (V8::UseCrankshaft()) { | 2593 // We call indirectly through the code field in the function to |
2595 // TODO(kasperl): For now, we always call indirectly through the | 2594 // allow recompilation to take effect without changing any of the |
2596 // code field in the function to allow recompilation to take effect | 2595 // call sites. |
2597 // without changing any of the call sites. | 2596 __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); |
2598 __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); | 2597 __ InvokeCode(r3, expected, arguments(), JUMP_FUNCTION, |
2599 __ InvokeCode(r3, expected, arguments(), JUMP_FUNCTION, | 2598 NullCallWrapper(), call_kind); |
2600 NullCallWrapper(), call_kind); | |
2601 } else { | |
2602 __ InvokeCode(code, expected, arguments(), RelocInfo::CODE_TARGET, | |
2603 JUMP_FUNCTION, call_kind); | |
2604 } | |
2605 | 2599 |
2606 // Handle call cache miss. | 2600 // Handle call cache miss. |
2607 __ bind(&miss); | 2601 __ bind(&miss); |
2608 __ IncrementCounter(counters->call_global_inline_miss(), 1, r1, r3); | 2602 __ IncrementCounter(counters->call_global_inline_miss(), 1, r1, r3); |
2609 MaybeObject* maybe_result = GenerateMissBranch(); | 2603 MaybeObject* maybe_result = GenerateMissBranch(); |
2610 if (maybe_result->IsFailure()) return maybe_result; | 2604 if (maybe_result->IsFailure()) return maybe_result; |
2611 | 2605 |
2612 // Return the generated code. | 2606 // Return the generated code. |
2613 return GetCode(NORMAL, name); | 2607 return GetCode(NORMAL, name); |
2614 } | 2608 } |
(...skipping 1845 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4460 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); | 4454 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); |
4461 __ Jump(ic_miss, RelocInfo::CODE_TARGET); | 4455 __ Jump(ic_miss, RelocInfo::CODE_TARGET); |
4462 } | 4456 } |
4463 | 4457 |
4464 | 4458 |
4465 #undef __ | 4459 #undef __ |
4466 | 4460 |
4467 } } // namespace v8::internal | 4461 } } // namespace v8::internal |
4468 | 4462 |
4469 #endif // V8_TARGET_ARCH_ARM | 4463 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |