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

Side by Side Diff: src/debug/debug-evaluate.cc

Issue 2634523002: [debugger] whitelist some builtins as side-effect free. (Closed)
Patch Set: fix Created 3 years, 11 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
« no previous file with comments | « src/debug/debug.h ('k') | test/debugger/debug/debug-evaluate-no-side-effect-builtins.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/debug/debug-evaluate.h" 5 #include "src/debug/debug-evaluate.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/compiler.h" 8 #include "src/compiler.h"
9 #include "src/contexts.h" 9 #include "src/contexts.h"
10 #include "src/debug/debug-frames.h" 10 #include "src/debug/debug-frames.h"
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 } else if (local_function->shared()->scope_info()->HasReceiver() && 251 } else if (local_function->shared()->scope_info()->HasReceiver() &&
252 !frame_->receiver()->IsTheHole(isolate_)) { 252 !frame_->receiver()->IsTheHole(isolate_)) {
253 recv = handle(frame_->receiver(), isolate_); 253 recv = handle(frame_->receiver(), isolate_);
254 } 254 }
255 JSObject::SetOwnPropertyIgnoreAttributes(target, name, recv, NONE).Check(); 255 JSObject::SetOwnPropertyIgnoreAttributes(target, name, recv, NONE).Check();
256 } 256 }
257 257
258 namespace { 258 namespace {
259 259
260 bool IntrinsicHasNoSideEffect(Runtime::FunctionId id) { 260 bool IntrinsicHasNoSideEffect(Runtime::FunctionId id) {
261 DCHECK_EQ(Runtime::INLINE, Runtime::FunctionForId(id)->intrinsic_type);
262 switch (id) { 261 switch (id) {
263 // Whitelist for intrinsics. 262 // Whitelist for intrinsics amd runtime functions.
263 // Conversions.
264 case Runtime::kToInteger:
265 case Runtime::kInlineToInteger:
266 case Runtime::kToObject:
264 case Runtime::kInlineToObject: 267 case Runtime::kInlineToObject:
268 case Runtime::kToString:
269 case Runtime::kInlineToString:
270 case Runtime::kToLength:
271 case Runtime::kInlineToLength:
272 // Loads.
273 case Runtime::kLoadLookupSlotForCall:
274 // Errors.
275 case Runtime::kThrowReferenceError:
276 // Strings.
277 case Runtime::kInlineStringCharCodeAt:
278 case Runtime::kStringCharCodeAt:
279 case Runtime::kStringIndexOf:
280 case Runtime::kStringReplaceOneCharWithString:
281 case Runtime::kSubString:
282 case Runtime::kInlineSubString:
283 case Runtime::kStringToLowerCase:
284 case Runtime::kStringToUpperCase:
285 case Runtime::kRegExpInternalReplace:
286 // Literals.
287 case Runtime::kCreateArrayLiteral:
288 case Runtime::kCreateObjectLiteral:
289 case Runtime::kCreateRegExpLiteral:
290 // Misc.
291 case Runtime::kInlineCall:
292 case Runtime::kCall:
293 case Runtime::kInlineMaxSmi:
294 case Runtime::kMaxSmi:
265 return true; 295 return true;
266 default: 296 default:
267 if (FLAG_trace_side_effect_free_debug_evaluate) { 297 if (FLAG_trace_side_effect_free_debug_evaluate) {
268 PrintF("[debug-evaluate] intrinsic %s may cause side effect.\n", 298 PrintF("[debug-evaluate] intrinsic %s may cause side effect.\n",
269 Runtime::FunctionForId(id)->name); 299 Runtime::FunctionForId(id)->name);
270 } 300 }
271 return false; 301 return false;
272 }
273 }
274
275 bool RuntimeFunctionHasNoSideEffect(Runtime::FunctionId id) {
276 DCHECK_EQ(Runtime::RUNTIME, Runtime::FunctionForId(id)->intrinsic_type);
277 switch (id) {
278 // Whitelist for runtime functions.
279 case Runtime::kToObject:
280 case Runtime::kLoadLookupSlotForCall:
281 case Runtime::kThrowReferenceError:
282 return true;
283 default:
284 if (FLAG_trace_side_effect_free_debug_evaluate) {
285 PrintF("[debug-evaluate] runtime %s may cause side effect.\n",
286 Runtime::FunctionForId(id)->name);
287 }
288 return false;
289 } 302 }
290 } 303 }
291 304
292 bool BytecodeHasNoSideEffect(interpreter::Bytecode bytecode) { 305 bool BytecodeHasNoSideEffect(interpreter::Bytecode bytecode) {
293 typedef interpreter::Bytecode Bytecode; 306 typedef interpreter::Bytecode Bytecode;
294 typedef interpreter::Bytecodes Bytecodes; 307 typedef interpreter::Bytecodes Bytecodes;
295 if (Bytecodes::IsWithoutExternalSideEffects(bytecode)) return true; 308 if (Bytecodes::IsWithoutExternalSideEffects(bytecode)) return true;
296 if (Bytecodes::IsCallOrNew(bytecode)) return true; 309 if (Bytecodes::IsCallOrNew(bytecode)) return true;
310 if (Bytecodes::WritesBooleanToAccumulator(bytecode)) return true;
311 if (Bytecodes::IsJumpIfToBoolean(bytecode)) return true;
312 if (Bytecodes::IsPrefixScalingBytecode(bytecode)) return true;
297 switch (bytecode) { 313 switch (bytecode) {
298 // Whitelist for bytecodes. 314 // Whitelist for bytecodes.
299 case Bytecode::kStackCheck: 315 // Loads.
300 case Bytecode::kLdaLookupSlot: 316 case Bytecode::kLdaLookupSlot:
301 case Bytecode::kLdaGlobal: 317 case Bytecode::kLdaGlobal:
302 case Bytecode::kLdaNamedProperty: 318 case Bytecode::kLdaNamedProperty:
303 case Bytecode::kLdaKeyedProperty: 319 case Bytecode::kLdaKeyedProperty:
320 // Arithmetics.
304 case Bytecode::kAdd: 321 case Bytecode::kAdd:
322 case Bytecode::kAddSmi:
323 case Bytecode::kSub:
324 case Bytecode::kSubSmi:
325 case Bytecode::kMul:
326 case Bytecode::kDiv:
327 case Bytecode::kMod:
328 case Bytecode::kBitwiseAnd:
329 case Bytecode::kBitwiseAndSmi:
330 case Bytecode::kBitwiseOr:
331 case Bytecode::kBitwiseOrSmi:
332 case Bytecode::kBitwiseXor:
333 case Bytecode::kShiftLeft:
334 case Bytecode::kShiftLeftSmi:
335 case Bytecode::kShiftRight:
336 case Bytecode::kShiftRightSmi:
337 case Bytecode::kShiftRightLogical:
338 case Bytecode::kInc:
339 case Bytecode::kDec:
340 case Bytecode::kLogicalNot:
341 case Bytecode::kToBooleanLogicalNot:
342 case Bytecode::kTypeOf:
343 // Contexts.
344 case Bytecode::kCreateBlockContext:
345 case Bytecode::kCreateCatchContext:
346 case Bytecode::kCreateFunctionContext:
347 case Bytecode::kCreateEvalContext:
348 case Bytecode::kCreateWithContext:
349 // Literals.
350 case Bytecode::kCreateArrayLiteral:
351 case Bytecode::kCreateObjectLiteral:
352 case Bytecode::kCreateRegExpLiteral:
353 // Misc.
354 case Bytecode::kCreateUnmappedArguments:
355 case Bytecode::kThrow:
356 case Bytecode::kIllegal:
357 case Bytecode::kCallJSRuntime:
358 case Bytecode::kStackCheck:
305 case Bytecode::kReturn: 359 case Bytecode::kReturn:
306 case Bytecode::kCreateCatchContext:
307 case Bytecode::kSetPendingMessage: 360 case Bytecode::kSetPendingMessage:
308 return true; 361 return true;
309 default: 362 default:
310 if (FLAG_trace_side_effect_free_debug_evaluate) { 363 if (FLAG_trace_side_effect_free_debug_evaluate) {
311 PrintF("[debug-evaluate] bytecode %s may cause side effect.\n", 364 PrintF("[debug-evaluate] bytecode %s may cause side effect.\n",
312 Bytecodes::ToString(bytecode)); 365 Bytecodes::ToString(bytecode));
313 } 366 }
314 return false; 367 return false;
315 } 368 }
316 } 369 }
317 370
318 bool BuiltinHasNoSideEffect(Builtins::Name id) { 371 bool BuiltinHasNoSideEffect(Builtins::Name id) {
319 switch (id) { 372 switch (id) {
320 // Whitelist for builtins. 373 // Whitelist for builtins.
374 // Math builtins.
375 case Builtins::kMathAbs:
376 case Builtins::kMathAcos:
377 case Builtins::kMathAcosh:
378 case Builtins::kMathAsin:
379 case Builtins::kMathAsinh:
380 case Builtins::kMathAtan:
381 case Builtins::kMathAtanh:
382 case Builtins::kMathAtan2:
383 case Builtins::kMathCeil:
384 case Builtins::kMathCbrt:
385 case Builtins::kMathExpm1:
386 case Builtins::kMathClz32:
387 case Builtins::kMathCos:
388 case Builtins::kMathCosh:
389 case Builtins::kMathExp:
390 case Builtins::kMathFloor:
391 case Builtins::kMathFround:
392 case Builtins::kMathHypot:
393 case Builtins::kMathImul:
394 case Builtins::kMathLog:
395 case Builtins::kMathLog1p:
396 case Builtins::kMathLog2:
397 case Builtins::kMathLog10:
398 case Builtins::kMathMax:
399 case Builtins::kMathMin:
400 case Builtins::kMathPow:
401 case Builtins::kMathRandom:
402 case Builtins::kMathRound:
403 case Builtins::kMathSign:
321 case Builtins::kMathSin: 404 case Builtins::kMathSin:
405 case Builtins::kMathSinh:
406 case Builtins::kMathSqrt:
407 case Builtins::kMathTan:
408 case Builtins::kMathTanh:
409 case Builtins::kMathTrunc:
410 // Number builtins.
411 case Builtins::kNumberConstructor:
412 case Builtins::kNumberIsFinite:
413 case Builtins::kNumberIsInteger:
414 case Builtins::kNumberIsNaN:
415 case Builtins::kNumberIsSafeInteger:
416 case Builtins::kNumberParseFloat:
417 case Builtins::kNumberParseInt:
418 case Builtins::kNumberPrototypeToExponential:
419 case Builtins::kNumberPrototypeToFixed:
420 case Builtins::kNumberPrototypeToPrecision:
421 case Builtins::kNumberPrototypeToString:
422 case Builtins::kNumberPrototypeValueOf:
423 // String builtins. Strings are immutable.
424 case Builtins::kStringFromCharCode:
425 case Builtins::kStringFromCodePoint:
426 case Builtins::kStringConstructor:
427 case Builtins::kStringPrototypeCharAt:
428 case Builtins::kStringPrototypeCharCodeAt:
429 case Builtins::kStringPrototypeEndsWith:
430 case Builtins::kStringPrototypeIncludes:
431 case Builtins::kStringPrototypeIndexOf:
432 case Builtins::kStringPrototypeLastIndexOf:
433 case Builtins::kStringPrototypeStartsWith:
434 case Builtins::kStringPrototypeSubstr:
435 case Builtins::kStringPrototypeSubstring:
436 case Builtins::kStringPrototypeToString:
437 case Builtins::kStringPrototypeTrim:
438 case Builtins::kStringPrototypeTrimLeft:
439 case Builtins::kStringPrototypeTrimRight:
440 case Builtins::kStringPrototypeValueOf:
441 // JSON builtins.
442 case Builtins::kJsonParse:
443 case Builtins::kJsonStringify:
322 return true; 444 return true;
323 default: 445 default:
324 if (FLAG_trace_side_effect_free_debug_evaluate) { 446 if (FLAG_trace_side_effect_free_debug_evaluate) {
325 PrintF("[debug-evaluate] built-in %s may cause side effect.\n", 447 PrintF("[debug-evaluate] built-in %s may cause side effect.\n",
326 Builtins::name(id)); 448 Builtins::name(id));
327 } 449 }
328 return false; 450 return false;
329 } 451 }
330 } 452 }
331 453
(...skipping 15 matching lines...) Expand all
347 469
348 if (info->HasBytecodeArray()) { 470 if (info->HasBytecodeArray()) {
349 // Check bytecodes against whitelist. 471 // Check bytecodes against whitelist.
350 Handle<BytecodeArray> bytecode_array(info->bytecode_array()); 472 Handle<BytecodeArray> bytecode_array(info->bytecode_array());
351 if (FLAG_trace_side_effect_free_debug_evaluate) bytecode_array->Print(); 473 if (FLAG_trace_side_effect_free_debug_evaluate) bytecode_array->Print();
352 for (interpreter::BytecodeArrayIterator it(bytecode_array); !it.done(); 474 for (interpreter::BytecodeArrayIterator it(bytecode_array); !it.done();
353 it.Advance()) { 475 it.Advance()) {
354 interpreter::Bytecode bytecode = it.current_bytecode(); 476 interpreter::Bytecode bytecode = it.current_bytecode();
355 477
356 if (interpreter::Bytecodes::IsCallRuntime(bytecode)) { 478 if (interpreter::Bytecodes::IsCallRuntime(bytecode)) {
357 if (bytecode == interpreter::Bytecode::kInvokeIntrinsic) { 479 Runtime::FunctionId id =
358 Runtime::FunctionId id = it.GetIntrinsicIdOperand(0); 480 (bytecode == interpreter::Bytecode::kInvokeIntrinsic)
359 if (IntrinsicHasNoSideEffect(id)) continue; 481 ? it.GetIntrinsicIdOperand(0)
360 } else { 482 : it.GetRuntimeIdOperand(0);
361 Runtime::FunctionId id = it.GetRuntimeIdOperand(0); 483 if (IntrinsicHasNoSideEffect(id)) continue;
362 if (RuntimeFunctionHasNoSideEffect(id)) continue;
363 }
364 return false; 484 return false;
365 } 485 }
366 486
367 if (BytecodeHasNoSideEffect(bytecode)) continue; 487 if (BytecodeHasNoSideEffect(bytecode)) continue;
368 488
369 // Did not match whitelist. 489 // Did not match whitelist.
370 return false; 490 return false;
371 } 491 }
372 return true; 492 return true;
373 } else { 493 } else {
(...skipping 16 matching lines...) Expand all
390 510
391 if (FLAG_trace_side_effect_free_debug_evaluate) { 511 if (FLAG_trace_side_effect_free_debug_evaluate) {
392 PrintF("[debug-evaluate] API Callback at %p may cause side effect.\n", 512 PrintF("[debug-evaluate] API Callback at %p may cause side effect.\n",
393 reinterpret_cast<void*>(function_addr)); 513 reinterpret_cast<void*>(function_addr));
394 } 514 }
395 return false; 515 return false;
396 } 516 }
397 517
398 } // namespace internal 518 } // namespace internal
399 } // namespace v8 519 } // namespace v8
OLDNEW
« no previous file with comments | « src/debug/debug.h ('k') | test/debugger/debug/debug-evaluate-no-side-effect-builtins.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698