OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "platform/utils.h" | 5 #include "platform/utils.h" |
6 | 6 |
7 #include "vm/allocation.h" | 7 #include "vm/allocation.h" |
8 #include "vm/atomic.h" | 8 #include "vm/atomic.h" |
9 #include "vm/code_patcher.h" | 9 #include "vm/code_patcher.h" |
10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
(...skipping 1950 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1961 const InterruptedThreadState& state, | 1961 const InterruptedThreadState& state, |
1962 void* data) { | 1962 void* data) { |
1963 Isolate* isolate = reinterpret_cast<Isolate*>(data); | 1963 Isolate* isolate = reinterpret_cast<Isolate*>(data); |
1964 if ((isolate == NULL) || (Dart::vm_isolate() == NULL)) { | 1964 if ((isolate == NULL) || (Dart::vm_isolate() == NULL)) { |
1965 // No isolate. | 1965 // No isolate. |
1966 return; | 1966 return; |
1967 } | 1967 } |
1968 | 1968 |
1969 ASSERT(isolate != Dart::vm_isolate()); | 1969 ASSERT(isolate != Dart::vm_isolate()); |
1970 | 1970 |
| 1971 uintptr_t sp = 0; |
| 1972 if ((isolate->stub_code() != NULL) && |
| 1973 (isolate->top_exit_frame_info() == 0) && |
| 1974 (isolate->vm_tag() == VMTag::kDartTagId)) { |
| 1975 // If we're in Dart code, use the Dart stack pointer. |
| 1976 sp = state.dsp; |
| 1977 } else { |
| 1978 // If we're in runtime code, use the C stack pointer. |
| 1979 sp = state.csp; |
| 1980 } |
| 1981 |
1971 IsolateProfilerData* profiler_data = isolate->profiler_data(); | 1982 IsolateProfilerData* profiler_data = isolate->profiler_data(); |
1972 if (profiler_data == NULL) { | 1983 if (profiler_data == NULL) { |
1973 // Profiler not initialized. | 1984 // Profiler not initialized. |
1974 return; | 1985 return; |
1975 } | 1986 } |
1976 | 1987 |
1977 SampleBuffer* sample_buffer = profiler_data->sample_buffer(); | 1988 SampleBuffer* sample_buffer = profiler_data->sample_buffer(); |
1978 if (sample_buffer == NULL) { | 1989 if (sample_buffer == NULL) { |
1979 // Profiler not initialized. | 1990 // Profiler not initialized. |
1980 return; | 1991 return; |
1981 } | 1992 } |
1982 | 1993 |
1983 if ((state.sp == 0) || (state.fp == 0) || (state.pc == 0)) { | 1994 if ((sp == 0) || (state.fp == 0) || (state.pc == 0)) { |
1984 // None of these registers should be zero. | 1995 // None of these registers should be zero. |
1985 return; | 1996 return; |
1986 } | 1997 } |
1987 | 1998 |
1988 if (state.sp > state.fp) { | 1999 if (sp > state.fp) { |
1989 // Assuming the stack grows down, we should never have a stack pointer above | 2000 // Assuming the stack grows down, we should never have a stack pointer above |
1990 // the frame pointer. | 2001 // the frame pointer. |
1991 return; | 2002 return; |
1992 } | 2003 } |
1993 | 2004 |
1994 if (StubCode::InJumpToExceptionHandlerStub(state.pc)) { | 2005 if (StubCode::InJumpToExceptionHandlerStub(state.pc)) { |
1995 // The JumpToExceptionHandler stub manually adjusts the stack pointer, | 2006 // The JumpToExceptionHandler stub manually adjusts the stack pointer, |
1996 // frame pointer, and some isolate state before jumping to a catch entry. | 2007 // frame pointer, and some isolate state before jumping to a catch entry. |
1997 // It is not safe to walk the stack when executing this stub. | 2008 // It is not safe to walk the stack when executing this stub. |
1998 return; | 2009 return; |
1999 } | 2010 } |
2000 | 2011 |
2001 uword stack_lower = 0; | 2012 uword stack_lower = 0; |
2002 uword stack_upper = 0; | 2013 uword stack_upper = 0; |
2003 isolate->GetProfilerStackBounds(&stack_lower, &stack_upper); | 2014 isolate->GetProfilerStackBounds(&stack_lower, &stack_upper); |
2004 if ((stack_lower == 0) || (stack_upper == 0)) { | 2015 if ((stack_lower == 0) || (stack_upper == 0)) { |
2005 // Could not get stack boundary. | 2016 // Could not get stack boundary. |
2006 return; | 2017 return; |
2007 } | 2018 } |
2008 | 2019 |
2009 if (state.sp > stack_lower) { | 2020 if (sp > stack_lower) { |
2010 // The stack pointer gives us a tighter lower bound. | 2021 // The stack pointer gives us a tighter lower bound. |
2011 stack_lower = state.sp; | 2022 stack_lower = sp; |
2012 } | 2023 } |
2013 | 2024 |
2014 if (stack_lower >= stack_upper) { | 2025 if (stack_lower >= stack_upper) { |
2015 // Stack boundary is invalid. | 2026 // Stack boundary is invalid. |
2016 return; | 2027 return; |
2017 } | 2028 } |
2018 | 2029 |
2019 if ((state.sp < stack_lower) || (state.sp >= stack_upper)) { | 2030 if ((sp < stack_lower) || (sp >= stack_upper)) { |
2020 // Stack pointer is outside isolate stack boundary. | 2031 // Stack pointer is outside isolate stack boundary. |
2021 return; | 2032 return; |
2022 } | 2033 } |
2023 | 2034 |
2024 if ((state.fp < stack_lower) || (state.fp >= stack_upper)) { | 2035 if ((state.fp < stack_lower) || (state.fp >= stack_upper)) { |
2025 // Frame pointer is outside isolate stack boundary. | 2036 // Frame pointer is outside isolate stack boundary. |
2026 return; | 2037 return; |
2027 } | 2038 } |
2028 | 2039 |
2029 // At this point we have a valid stack boundary for this isolate and | 2040 // At this point we have a valid stack boundary for this isolate and |
2030 // know that our initial stack and frame pointers are within the boundary. | 2041 // know that our initial stack and frame pointers are within the boundary. |
2031 | 2042 |
2032 // Increment counter for vm tag. | 2043 // Increment counter for vm tag. |
2033 VMTagCounters* counters = isolate->vm_tag_counters(); | 2044 VMTagCounters* counters = isolate->vm_tag_counters(); |
2034 ASSERT(counters != NULL); | 2045 ASSERT(counters != NULL); |
2035 counters->Increment(isolate->vm_tag()); | 2046 counters->Increment(isolate->vm_tag()); |
2036 | 2047 |
2037 // Setup sample. | 2048 // Setup sample. |
2038 Sample* sample = sample_buffer->ReserveSample(); | 2049 Sample* sample = sample_buffer->ReserveSample(); |
2039 sample->Init(isolate, OS::GetCurrentTimeMicros(), state.tid); | 2050 sample->Init(isolate, OS::GetCurrentTimeMicros(), state.tid); |
2040 sample->set_vm_tag(isolate->vm_tag()); | 2051 sample->set_vm_tag(isolate->vm_tag()); |
2041 sample->set_user_tag(isolate->user_tag()); | 2052 sample->set_user_tag(isolate->user_tag()); |
2042 sample->set_sp(state.sp); | 2053 sample->set_sp(sp); |
2043 sample->set_fp(state.fp); | 2054 sample->set_fp(state.fp); |
2044 #if !(defined(TARGET_OS_WINDOWS) && defined(TARGET_ARCH_X64)) | 2055 #if !(defined(TARGET_OS_WINDOWS) && defined(TARGET_ARCH_X64)) |
2045 // It is never safe to read other thread's stack unless on Win64 | 2056 // It is never safe to read other thread's stack unless on Win64 |
2046 // other thread is inside Dart code. | 2057 // other thread is inside Dart code. |
2047 SetPCMarkerIfSafe(sample); | 2058 SetPCMarkerIfSafe(sample); |
2048 #endif | 2059 #endif |
2049 | 2060 |
2050 // Walk the call stack. | 2061 // Walk the call stack. |
2051 if (FLAG_profile_vm) { | 2062 if (FLAG_profile_vm) { |
2052 // Always walk the native stack collecting both native and Dart frames. | 2063 // Always walk the native stack collecting both native and Dart frames. |
2053 ProfilerNativeStackWalker stackWalker(sample, | 2064 ProfilerNativeStackWalker stackWalker(sample, |
2054 stack_lower, | 2065 stack_lower, |
2055 stack_upper, | 2066 stack_upper, |
2056 state.pc, | 2067 state.pc, |
2057 state.fp, | 2068 state.fp, |
2058 state.sp); | 2069 sp); |
2059 stackWalker.walk(); | 2070 stackWalker.walk(); |
2060 } else { | 2071 } else { |
2061 // Attempt to walk only the Dart call stack, falling back to walking | 2072 // Attempt to walk only the Dart call stack, falling back to walking |
2062 // the native stack. | 2073 // the native stack. |
2063 if ((isolate->stub_code() != NULL) && | 2074 if ((isolate->stub_code() != NULL) && |
2064 (isolate->top_exit_frame_info() != 0) && | 2075 (isolate->top_exit_frame_info() != 0) && |
2065 (isolate->vm_tag() != VMTag::kDartTagId)) { | 2076 (isolate->vm_tag() != VMTag::kDartTagId)) { |
2066 // We have a valid exit frame info, use the Dart stack walker. | 2077 // We have a valid exit frame info, use the Dart stack walker. |
2067 ProfilerDartExitStackWalker stackWalker(isolate, sample); | 2078 ProfilerDartExitStackWalker stackWalker(isolate, sample); |
2068 stackWalker.walk(); | 2079 stackWalker.walk(); |
2069 } else if ((isolate->stub_code() != NULL) && | 2080 } else if ((isolate->stub_code() != NULL) && |
2070 (isolate->top_exit_frame_info() == 0) && | 2081 (isolate->top_exit_frame_info() == 0) && |
2071 (isolate->vm_tag() == VMTag::kDartTagId)) { | 2082 (isolate->vm_tag() == VMTag::kDartTagId)) { |
2072 // We are executing Dart code. We have frame pointers. | 2083 // We are executing Dart code. We have frame pointers. |
2073 ProfilerDartStackWalker stackWalker(isolate, | 2084 ProfilerDartStackWalker stackWalker(isolate, |
2074 sample, | 2085 sample, |
2075 stack_lower, | 2086 stack_lower, |
2076 stack_upper, | 2087 stack_upper, |
2077 state.pc, | 2088 state.pc, |
2078 state.fp, | 2089 state.fp, |
2079 state.sp); | 2090 sp); |
2080 stackWalker.walk(); | 2091 stackWalker.walk(); |
2081 } else { | 2092 } else { |
2082 #if defined(TARGET_OS_WINDOWS) && defined(TARGET_ARCH_X64) | 2093 #if defined(TARGET_OS_WINDOWS) && defined(TARGET_ARCH_X64) |
2083 // ProfilerNativeStackWalker is known to cause crashes on Win64. | 2094 // ProfilerNativeStackWalker is known to cause crashes on Win64. |
2084 // BUG=20423. | 2095 // BUG=20423. |
2085 sample->set_ignore_sample(true); | 2096 sample->set_ignore_sample(true); |
2086 #else | 2097 #else |
2087 // Fall back to an extremely conservative stack walker. | 2098 // Fall back to an extremely conservative stack walker. |
2088 ProfilerNativeStackWalker stackWalker(sample, | 2099 ProfilerNativeStackWalker stackWalker(sample, |
2089 stack_lower, | 2100 stack_lower, |
2090 stack_upper, | 2101 stack_upper, |
2091 state.pc, | 2102 state.pc, |
2092 state.fp, | 2103 state.fp, |
2093 state.sp); | 2104 sp); |
2094 stackWalker.walk(); | 2105 stackWalker.walk(); |
2095 #endif | 2106 #endif |
2096 } | 2107 } |
2097 } | 2108 } |
2098 } | 2109 } |
2099 | 2110 |
2100 } // namespace dart | 2111 } // namespace dart |
OLD | NEW |