Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(452)

Side by Side Diff: test/cctest/test-log-ia32.cc

Issue 92121: Materializing a frame element on the stack by pushing it can cause the... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« src/arm/virtual-frame-arm.cc ('K') | « src/virtual-frame.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 the V8 project authors. All rights reserved.
2 // 2 //
3 // Tests of profiler-related functions from log.h 3 // Tests of profiler-related functions from log.h
4 4
5 #ifdef ENABLE_LOGGING_AND_PROFILING 5 #ifdef ENABLE_LOGGING_AND_PROFILING
6 6
7 #include <stdlib.h> 7 #include <stdlib.h>
8 8
9 #include "v8.h" 9 #include "v8.h"
10 10
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 // pure JS code is being executed 55 // pure JS code is being executed
56 static void DoTraceHideCEntryFPAddress(unsigned int fp) { 56 static void DoTraceHideCEntryFPAddress(unsigned int fp) {
57 v8::internal::Address saved_c_frame_fp = *(Top::c_entry_fp_address()); 57 v8::internal::Address saved_c_frame_fp = *(Top::c_entry_fp_address());
58 CHECK(saved_c_frame_fp); 58 CHECK(saved_c_frame_fp);
59 *(Top::c_entry_fp_address()) = 0; 59 *(Top::c_entry_fp_address()) = 0;
60 DoTrace(fp); 60 DoTrace(fp);
61 *(Top::c_entry_fp_address()) = saved_c_frame_fp; 61 *(Top::c_entry_fp_address()) = saved_c_frame_fp;
62 } 62 }
63 63
64 64
65 static void CheckRetAddrIsInFunction(const char* func_name,
66 unsigned int ret_addr,
67 unsigned int func_start_addr,
68 unsigned int func_len) {
69 printf("CheckRetAddrIsInFunction \"%s\": %08x %08x %08x\n",
70 func_name, func_start_addr, ret_addr, func_start_addr + func_len);
71 CHECK_GE(ret_addr, func_start_addr);
72 CHECK_GE(func_start_addr + func_len, ret_addr);
73 }
74
75
76 static void CheckRetAddrIsInJSFunction(const char* func_name,
77 unsigned int ret_addr,
78 Handle<JSFunction> func) {
79 v8::internal::Code* func_code = func->code();
80 CheckRetAddrIsInFunction(
81 func_name, ret_addr,
82 reinterpret_cast<unsigned int>(func_code->instruction_start()),
83 func_code->ExecutableSize());
84 }
85
86
87 // --- T r a c e E x t e n s i o n --- 65 // --- T r a c e E x t e n s i o n ---
88 66
89 class TraceExtension : public v8::Extension { 67 class TraceExtension : public v8::Extension {
90 public: 68 public:
91 TraceExtension() : v8::Extension("v8/trace", kSource) { } 69 TraceExtension() : v8::Extension("v8/trace", kSource) { }
92 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( 70 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
93 v8::Handle<String> name); 71 v8::Handle<String> name);
94 static v8::Handle<v8::Value> Trace(const v8::Arguments& args); 72 static v8::Handle<v8::Value> Trace(const v8::Arguments& args);
95 static v8::Handle<v8::Value> JSTrace(const v8::Arguments& args); 73 static v8::Handle<v8::Value> JSTrace(const v8::Arguments& args);
96 private: 74 private:
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 v8::Handle<v8::Value> TraceExtension::JSTrace(const v8::Arguments& args) { 112 v8::Handle<v8::Value> TraceExtension::JSTrace(const v8::Arguments& args) {
135 DoTraceHideCEntryFPAddress(GetFP(args)); 113 DoTraceHideCEntryFPAddress(GetFP(args));
136 return v8::Undefined(); 114 return v8::Undefined();
137 } 115 }
138 116
139 117
140 static TraceExtension kTraceExtension; 118 static TraceExtension kTraceExtension;
141 v8::DeclareExtension kTraceExtensionDeclaration(&kTraceExtension); 119 v8::DeclareExtension kTraceExtensionDeclaration(&kTraceExtension);
142 120
143 121
144 static void InitializeVM() {
145 if (env.IsEmpty()) {
146 v8::HandleScope scope;
147 const char* extensions[] = { "v8/trace" };
148 v8::ExtensionConfiguration config(1, extensions);
149 env = v8::Context::New(&config);
150 }
151 v8::HandleScope scope;
152 env->Enter();
153 }
154
155
156 static Handle<JSFunction> CompileFunction(const char* source) {
157 return v8::Utils::OpenHandle(*Script::Compile(String::New(source)));
158 }
159
160
161 static void CompileRun(const char* source) {
162 Script::Compile(String::New(source))->Run();
163 }
164
165
166 static Local<Value> GetGlobalProperty(const char* name) {
167 return env->Global()->Get(String::New(name));
168 }
169
170
171 static Handle<JSFunction> GetGlobalJSFunction(const char* name) {
172 Handle<JSFunction> js_func(JSFunction::cast(
173 *(v8::Utils::OpenHandle(
174 *GetGlobalProperty(name)))));
175 return js_func;
176 }
177
178
179 static void CheckRetAddrIsInJSFunction(const char* func_name,
180 unsigned int ret_addr) {
181 CheckRetAddrIsInJSFunction(func_name, ret_addr,
182 GetGlobalJSFunction(func_name));
183 }
184
185
186 static void SetGlobalProperty(const char* name, Local<Value> value) {
187 env->Global()->Set(String::New(name), value);
188 }
189
190
191 static bool Patch(byte* from,
192 size_t num,
193 byte* original,
194 byte* patch,
195 size_t patch_len) {
196 byte* to = from + num;
197 do {
198 from = static_cast<byte*>(memchr(from, *original, to - from));
199 CHECK(from != NULL);
200 if (memcmp(original, from, patch_len) == 0) {
201 memcpy(from, patch, patch_len);
202 return true;
203 } else {
204 from++;
205 }
206 } while (to - from > 0);
207 return false;
208 }
209
210
211 // Creates a global function named 'func_name' that calls the tracing
212 // function 'trace_func_name' with an actual EBP register value,
213 // shifted right to be presented as Smi.
214 static void CreateTraceCallerFunction(const char* func_name,
215 const char* trace_func_name) {
216 ::v8::internal::EmbeddedVector<char, 256> trace_call_buf;
217 ::v8::internal::OS::SNPrintF(trace_call_buf, "%s(0x6666);", trace_func_name);
218 Handle<JSFunction> func = CompileFunction(trace_call_buf.start());
219 CHECK(!func.is_null());
220 v8::internal::Code* func_code = func->code();
221 CHECK(func_code->IsCode());
222
223 // push 0xcccc (= 0x6666 << 1)
224 byte original[] = { 0x68, 0xcc, 0xcc, 0x00, 0x00 };
225 // mov eax,ebp; shr eax; push eax;
226 byte patch[] = { 0x89, 0xe8, 0xd1, 0xe8, 0x50 };
227 // Patch generated code to replace pushing of a constant with
228 // pushing of ebp contents in a Smi
229 CHECK(Patch(func_code->instruction_start(),
230 func_code->instruction_size(),
231 original, patch, sizeof(patch)));
232
233 SetGlobalProperty(func_name, v8::ToApi<Value>(func));
234 }
235
236
237 TEST(CFromJSStackTrace) {
238 TickSample sample;
239 StackTracer tracer(reinterpret_cast<unsigned int>(&sample));
240 InitTraceEnv(&tracer, &sample);
241
242 InitializeVM();
243 v8::HandleScope scope;
244 CreateTraceCallerFunction("JSFuncDoTrace", "trace");
245 CompileRun(
246 "function JSTrace() {"
247 " JSFuncDoTrace();"
248 "};\n"
249 "JSTrace();");
250 CHECK_GT(sample.frames_count, 1);
251 // Stack sampling will start from the first JS function, i.e. "JSFuncDoTrace"
252 CheckRetAddrIsInJSFunction("JSFuncDoTrace",
253 reinterpret_cast<unsigned int>(sample.stack[0]));
254 CheckRetAddrIsInJSFunction("JSTrace",
255 reinterpret_cast<unsigned int>(sample.stack[1]));
256 }
257
258
259 TEST(PureJSStackTrace) {
260 TickSample sample;
261 StackTracer tracer(reinterpret_cast<unsigned int>(&sample));
262 InitTraceEnv(&tracer, &sample);
263
264 InitializeVM();
265 v8::HandleScope scope;
266 CreateTraceCallerFunction("JSFuncDoTrace", "js_trace");
267 CompileRun(
268 "function JSTrace() {"
269 " JSFuncDoTrace();"
270 "};\n"
271 "function OuterJSTrace() {"
272 " JSTrace();"
273 "};\n"
274 "OuterJSTrace();");
275 CHECK_GT(sample.frames_count, 1);
276 // Stack sampling will start from the caller of JSFuncDoTrace, i.e. "JSTrace"
277 CheckRetAddrIsInJSFunction("JSTrace",
278 reinterpret_cast<unsigned int>(sample.stack[0]));
279 CheckRetAddrIsInJSFunction("OuterJSTrace",
280 reinterpret_cast<unsigned int>(sample.stack[1]));
281 }
282
283
284 static void CFuncDoTrace() { 122 static void CFuncDoTrace() {
285 unsigned int fp; 123 unsigned int fp;
286 #ifdef __GNUC__ 124 #ifdef __GNUC__
287 fp = reinterpret_cast<unsigned int>(__builtin_frame_address(0)); 125 fp = reinterpret_cast<unsigned int>(__builtin_frame_address(0));
288 #elif defined _MSC_VER 126 #elif defined _MSC_VER
289 __asm mov [fp], ebp // NOLINT 127 __asm mov [fp], ebp // NOLINT
290 #endif 128 #endif
291 DoTrace(fp); 129 DoTrace(fp);
292 } 130 }
293 131
(...skipping 11 matching lines...) Expand all
305 TEST(PureCStackTrace) { 143 TEST(PureCStackTrace) {
306 TickSample sample; 144 TickSample sample;
307 StackTracer tracer(reinterpret_cast<unsigned int>(&sample)); 145 StackTracer tracer(reinterpret_cast<unsigned int>(&sample));
308 InitTraceEnv(&tracer, &sample); 146 InitTraceEnv(&tracer, &sample);
309 // Check that sampler doesn't crash 147 // Check that sampler doesn't crash
310 CHECK_EQ(10, CFunc(10)); 148 CHECK_EQ(10, CFunc(10));
311 } 149 }
312 150
313 151
314 #endif // ENABLE_LOGGING_AND_PROFILING 152 #endif // ENABLE_LOGGING_AND_PROFILING
OLDNEW
« src/arm/virtual-frame-arm.cc ('K') | « src/virtual-frame.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698