LCOV - code coverage report
Current view: top level - src/debug - debug-evaluate.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 125 130 96.2 %
Date: 2019-01-20 Functions: 14 14 100.0 %

          Line data    Source code
       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
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/debug/debug-evaluate.h"
       6             : 
       7             : #include "src/accessors.h"
       8             : #include "src/assembler-inl.h"
       9             : #include "src/compiler.h"
      10             : #include "src/contexts.h"
      11             : #include "src/debug/debug-frames.h"
      12             : #include "src/debug/debug-scopes.h"
      13             : #include "src/debug/debug.h"
      14             : #include "src/frames-inl.h"
      15             : #include "src/globals.h"
      16             : #include "src/interpreter/bytecode-array-iterator.h"
      17             : #include "src/interpreter/bytecodes.h"
      18             : #include "src/isolate-inl.h"
      19             : #include "src/snapshot/snapshot.h"
      20             : 
      21             : namespace v8 {
      22             : namespace internal {
      23             : 
      24       10442 : MaybeHandle<Object> DebugEvaluate::Global(Isolate* isolate,
      25             :                                           Handle<String> source,
      26             :                                           bool throw_on_side_effect) {
      27             :   // Disable breaks in side-effect free mode.
      28             :   DisableBreak disable_break_scope(isolate->debug(), throw_on_side_effect);
      29             : 
      30        8878 :   Handle<Context> context = isolate->native_context();
      31             :   ScriptOriginOptions origin_options(false, true);
      32             :   MaybeHandle<SharedFunctionInfo> maybe_function_info =
      33             :       Compiler::GetSharedFunctionInfoForScript(
      34             :           isolate, source,
      35             :           Compiler::ScriptDetails(isolate->factory()->empty_string()),
      36             :           origin_options, nullptr, nullptr, ScriptCompiler::kNoCompileOptions,
      37        8878 :           ScriptCompiler::kNoCacheNoReason, NOT_NATIVES_CODE);
      38             : 
      39             :   Handle<SharedFunctionInfo> shared_info;
      40        8878 :   if (!maybe_function_info.ToHandle(&shared_info)) return MaybeHandle<Object>();
      41             : 
      42             :   Handle<JSFunction> fun =
      43             :       isolate->factory()->NewFunctionFromSharedFunctionInfo(shared_info,
      44        8828 :                                                             context);
      45        9610 :   if (throw_on_side_effect) isolate->debug()->StartSideEffectCheckMode();
      46             :   MaybeHandle<Object> result = Execution::Call(
      47       17656 :       isolate, fun, Handle<JSObject>(context->global_proxy(), isolate), 0,
      48       17656 :       nullptr);
      49        9610 :   if (throw_on_side_effect) isolate->debug()->StopSideEffectCheckMode();
      50        8828 :   return result;
      51             : }
      52             : 
      53       11905 : MaybeHandle<Object> DebugEvaluate::Local(Isolate* isolate,
      54             :                                          StackFrame::Id frame_id,
      55             :                                          int inlined_jsframe_index,
      56             :                                          Handle<String> source,
      57             :                                          bool throw_on_side_effect) {
      58             :   // Handle the processing of break.
      59             :   DisableBreak disable_break_scope(isolate->debug());
      60             : 
      61             :   // Get the frame where the debugging is performed.
      62       11905 :   StackTraceFrameIterator it(isolate, frame_id);
      63       11905 :   if (!it.is_javascript()) return isolate->factory()->undefined_value();
      64             :   JavaScriptFrame* frame = it.javascript_frame();
      65             : 
      66             :   // This is not a lot different than DebugEvaluate::Global, except that
      67             :   // variables accessible by the function we are evaluating from are
      68             :   // materialized and included on top of the native context. Changes to
      69             :   // the materialized object are written back afterwards.
      70             :   // Note that the native context is taken from the original context chain,
      71             :   // which may not be the current native context of the isolate.
      72       23810 :   ContextBuilder context_builder(isolate, frame, inlined_jsframe_index);
      73       11905 :   if (isolate->has_pending_exception()) return MaybeHandle<Object>();
      74             : 
      75             :   Handle<Context> context = context_builder.evaluation_context();
      76       23810 :   Handle<JSObject> receiver(context->global_proxy(), isolate);
      77             :   MaybeHandle<Object> maybe_result =
      78             :       Evaluate(isolate, context_builder.outer_info(), context, receiver, source,
      79       23810 :                throw_on_side_effect);
      80       11905 :   if (!maybe_result.is_null()) context_builder.UpdateValues();
      81       11905 :   return maybe_result;
      82             : }
      83             : 
      84          85 : MaybeHandle<Object> DebugEvaluate::WithTopmostArguments(Isolate* isolate,
      85             :                                                         Handle<String> source) {
      86             :   // Handle the processing of break.
      87             :   DisableBreak disable_break_scope(isolate->debug());
      88             :   Factory* factory = isolate->factory();
      89          85 :   JavaScriptFrameIterator it(isolate);
      90             : 
      91             :   // Get context and receiver.
      92             :   Handle<Context> native_context(
      93         255 :       Context::cast(it.frame()->context())->native_context(), isolate);
      94             : 
      95             :   // Materialize arguments as property on an extension object.
      96          85 :   Handle<JSObject> materialized = factory->NewJSObjectWithNullProto();
      97             :   Handle<String> arguments_str = factory->arguments_string();
      98             :   JSObject::SetOwnPropertyIgnoreAttributes(
      99             :       materialized, arguments_str,
     100         170 :       Accessors::FunctionGetArguments(it.frame(), 0), NONE)
     101         170 :       .Check();
     102             : 
     103             :   // Materialize receiver.
     104             :   Handle<String> this_str = factory->this_string();
     105             :   JSObject::SetOwnPropertyIgnoreAttributes(
     106          85 :       materialized, this_str, Handle<Object>(it.frame()->receiver(), isolate),
     107         170 :       NONE)
     108         170 :       .Check();
     109             : 
     110             :   // Use extension object in a debug-evaluate scope.
     111             :   Handle<ScopeInfo> scope_info =
     112          85 :       ScopeInfo::CreateForWithScope(isolate, Handle<ScopeInfo>::null());
     113          85 :   scope_info->SetIsDebugEvaluateScope();
     114             :   Handle<Context> evaluation_context =
     115             :       factory->NewDebugEvaluateContext(native_context, scope_info, materialized,
     116          85 :                                        Handle<Context>(), Handle<StringSet>());
     117             :   Handle<SharedFunctionInfo> outer_info(
     118         170 :       native_context->empty_function()->shared(), isolate);
     119         170 :   Handle<JSObject> receiver(native_context->global_proxy(), isolate);
     120             :   const bool throw_on_side_effect = false;
     121             :   MaybeHandle<Object> maybe_result =
     122             :       Evaluate(isolate, outer_info, evaluation_context, receiver, source,
     123          85 :                throw_on_side_effect);
     124         170 :   return maybe_result;
     125             : }
     126             : 
     127             : // Compile and evaluate source for the given context.
     128       11990 : MaybeHandle<Object> DebugEvaluate::Evaluate(
     129        8292 :     Isolate* isolate, Handle<SharedFunctionInfo> outer_info,
     130             :     Handle<Context> context, Handle<Object> receiver, Handle<String> source,
     131             :     bool throw_on_side_effect) {
     132             :   Handle<JSFunction> eval_fun;
     133       23980 :   ASSIGN_RETURN_ON_EXCEPTION(
     134             :       isolate, eval_fun,
     135             :       Compiler::GetFunctionFromEval(source, outer_info, context,
     136             :                                     LanguageMode::kSloppy, NO_PARSE_RESTRICTION,
     137             :                                     kNoSourcePosition, kNoSourcePosition,
     138             :                                     kNoSourcePosition),
     139             :       Object);
     140             : 
     141             :   Handle<Object> result;
     142             :   bool success = false;
     143       16067 :   if (throw_on_side_effect) isolate->debug()->StartSideEffectCheckMode();
     144       11921 :   success = Execution::Call(isolate, eval_fun, receiver, 0, nullptr)
     145       23842 :                 .ToHandle(&result);
     146       16067 :   if (throw_on_side_effect) isolate->debug()->StopSideEffectCheckMode();
     147             :   if (!success) DCHECK(isolate->has_pending_exception());
     148       13067 :   return success ? result : MaybeHandle<Object>();
     149             : }
     150             : 
     151       11905 : Handle<SharedFunctionInfo> DebugEvaluate::ContextBuilder::outer_info() const {
     152       35715 :   return handle(frame_inspector_.GetFunction()->shared(), isolate_);
     153             : }
     154             : 
     155       11905 : DebugEvaluate::ContextBuilder::ContextBuilder(Isolate* isolate,
     156             :                                               JavaScriptFrame* frame,
     157             :                                               int inlined_jsframe_index)
     158             :     : isolate_(isolate),
     159             :       frame_inspector_(frame, inlined_jsframe_index, isolate),
     160             :       scope_iterator_(isolate, &frame_inspector_,
     161       11905 :                       ScopeIterator::COLLECT_NON_LOCALS) {
     162             :   Handle<Context> outer_context(frame_inspector_.GetFunction()->context(),
     163       23810 :                                 isolate);
     164       11905 :   evaluation_context_ = outer_context;
     165             :   Factory* factory = isolate->factory();
     166             : 
     167       23810 :   if (scope_iterator_.Done()) return;
     168             : 
     169             :   // To evaluate as if we were running eval at the point of the debug break,
     170             :   // we reconstruct the context chain as follows:
     171             :   //  - To make stack-allocated variables visible, we materialize them and
     172             :   //    use a debug-evaluate context to wrap both the materialized object and
     173             :   //    the original context.
     174             :   //  - We use the original context chain from the function context to the
     175             :   //    native context.
     176             :   //  - Between the function scope and the native context, we only resolve
     177             :   //    variable names that the current function already uses. Only for these
     178             :   //    names we can be sure that they will be correctly resolved. For the
     179             :   //    rest, we only resolve to with, script, and native contexts. We use a
     180             :   //    whitelist to implement that.
     181             :   // Context::Lookup has special handling for debug-evaluate contexts:
     182             :   //  - Look up in the materialized stack variables.
     183             :   //  - Look up in the original context.
     184             :   //  - Check the whitelist to find out whether to skip contexts during lookup.
     185       36524 :   for (; scope_iterator_.InInnerScope(); scope_iterator_.Next()) {
     186       12393 :     ScopeIterator::ScopeType scope_type = scope_iterator_.Type();
     187       12393 :     if (scope_type == ScopeIterator::ScopeTypeScript) break;
     188             :     ContextChainElement context_chain_element;
     189       13102 :     if (scope_type == ScopeIterator::ScopeTypeLocal ||
     190         787 :         scope_iterator_.DeclaresLocals(ScopeIterator::Mode::STACK)) {
     191             :       context_chain_element.materialized_object =
     192       11995 :           scope_iterator_.ScopeObject(ScopeIterator::Mode::STACK);
     193             :     }
     194       12315 :     if (scope_iterator_.HasContext()) {
     195        1036 :       context_chain_element.wrapped_context = scope_iterator_.CurrentContext();
     196             :     }
     197       12315 :     if (scope_type == ScopeIterator::ScopeTypeLocal) {
     198       11528 :       context_chain_element.whitelist = scope_iterator_.GetNonLocals();
     199             :     }
     200       12315 :     context_chain_.push_back(context_chain_element);
     201             :   }
     202             : 
     203             :   Handle<ScopeInfo> scope_info =
     204       23788 :       evaluation_context_->IsNativeContext()
     205             :           ? Handle<ScopeInfo>::null()
     206       25638 :           : handle(evaluation_context_->scope_info(), isolate);
     207       24209 :   for (auto rit = context_chain_.rbegin(); rit != context_chain_.rend();
     208             :        rit++) {
     209       12315 :     ContextChainElement element = *rit;
     210       12315 :     scope_info = ScopeInfo::CreateForWithScope(isolate, scope_info);
     211       12315 :     scope_info->SetIsDebugEvaluateScope();
     212             :     evaluation_context_ = factory->NewDebugEvaluateContext(
     213             :         evaluation_context_, scope_info, element.materialized_object,
     214       12315 :         element.wrapped_context, element.whitelist);
     215             :   }
     216             : }
     217             : 
     218             : 
     219       10690 : void DebugEvaluate::ContextBuilder::UpdateValues() {
     220       10690 :   scope_iterator_.Restart();
     221       32505 :   for (ContextChainElement& element : context_chain_) {
     222       11125 :     if (!element.materialized_object.is_null()) {
     223             :       Handle<FixedArray> keys =
     224             :           KeyAccumulator::GetKeys(element.materialized_object,
     225             :                                   KeyCollectionMode::kOwnOnly,
     226       10805 :                                   ENUMERABLE_STRINGS)
     227       21610 :               .ToHandleChecked();
     228             : 
     229      188330 :       for (int i = 0; i < keys->length(); i++) {
     230             :         DCHECK(keys->get(i)->IsString());
     231       83360 :         Handle<String> key(String::cast(keys->get(i)), isolate_);
     232             :         Handle<Object> value =
     233       83360 :             JSReceiver::GetDataProperty(element.materialized_object, key);
     234       83360 :         scope_iterator_.SetVariableValue(key, value);
     235             :       }
     236             :     }
     237       11125 :     scope_iterator_.Next();
     238             :   }
     239       10690 : }
     240             : 
     241             : namespace {
     242             : 
     243        1320 : bool IntrinsicHasNoSideEffect(Runtime::FunctionId id) {
     244             : // Use macro to include only the non-inlined version of an intrinsic.
     245             : #define INTRINSIC_WHITELIST(V)                \
     246             :   /* Conversions */                           \
     247             :   V(NumberToString)                           \
     248             :   V(ToBigInt)                                 \
     249             :   V(ToLength)                                 \
     250             :   V(ToNumber)                                 \
     251             :   V(ToObject)                                 \
     252             :   V(ToString)                                 \
     253             :   /* Type checks */                           \
     254             :   V(IsArray)                                  \
     255             :   V(IsFunction)                               \
     256             :   V(IsJSProxy)                                \
     257             :   V(IsJSReceiver)                             \
     258             :   V(IsRegExp)                                 \
     259             :   V(IsSmi)                                    \
     260             :   V(IsTypedArray)                             \
     261             :   /* Loads */                                 \
     262             :   V(LoadLookupSlotForCall)                    \
     263             :   V(GetProperty)                              \
     264             :   /* Arrays */                                \
     265             :   V(ArraySpeciesConstructor)                  \
     266             :   V(EstimateNumberOfElements)                 \
     267             :   V(GetArrayKeys)                             \
     268             :   V(HasComplexElements)                       \
     269             :   V(HasFastPackedElements)                    \
     270             :   V(NewArray)                                 \
     271             :   V(NormalizeElements)                        \
     272             :   V(PrepareElementsForSort)                   \
     273             :   V(TrySliceSimpleNonFastElements)            \
     274             :   V(TypedArrayGetBuffer)                      \
     275             :   /* Errors */                                \
     276             :   V(NewTypeError)                             \
     277             :   V(ReThrow)                                  \
     278             :   V(ThrowCalledNonCallable)                   \
     279             :   V(ThrowInvalidStringLength)                 \
     280             :   V(ThrowIteratorError)                       \
     281             :   V(ThrowIteratorResultNotAnObject)           \
     282             :   V(ThrowPatternAssignmentNonCoercible)       \
     283             :   V(ThrowReferenceError)                      \
     284             :   V(ThrowSymbolIteratorInvalid)               \
     285             :   /* Strings */                               \
     286             :   V(RegExpInternalReplace)                    \
     287             :   V(StringIncludes)                           \
     288             :   V(StringIndexOf)                            \
     289             :   V(StringReplaceOneCharWithString)           \
     290             :   V(StringSubstring)                          \
     291             :   V(StringToNumber)                           \
     292             :   V(StringTrim)                               \
     293             :   /* BigInts */                               \
     294             :   V(BigIntEqualToBigInt)                      \
     295             :   V(BigIntToBoolean)                          \
     296             :   V(BigIntToNumber)                           \
     297             :   /* Literals */                              \
     298             :   V(CreateArrayLiteral)                       \
     299             :   V(CreateArrayLiteralWithoutAllocationSite)  \
     300             :   V(CreateObjectLiteral)                      \
     301             :   V(CreateObjectLiteralWithoutAllocationSite) \
     302             :   V(CreateRegExpLiteral)                      \
     303             :   /* Called from builtins */                  \
     304             :   V(AllocateInNewSpace)                       \
     305             :   V(AllocateInTargetSpace)                    \
     306             :   V(AllocateSeqOneByteString)                 \
     307             :   V(AllocateSeqTwoByteString)                 \
     308             :   V(ArrayIncludes_Slow)                       \
     309             :   V(ArrayIndexOf)                             \
     310             :   V(ArrayIsArray)                             \
     311             :   V(ClassOf)                                  \
     312             :   V(GetFunctionName)                          \
     313             :   V(GetOwnPropertyDescriptor)                 \
     314             :   V(GlobalPrint)                              \
     315             :   V(HasProperty)                              \
     316             :   V(ObjectCreate)                             \
     317             :   V(ObjectEntries)                            \
     318             :   V(ObjectEntriesSkipFastPath)                \
     319             :   V(ObjectHasOwnProperty)                     \
     320             :   V(ObjectValues)                             \
     321             :   V(ObjectValuesSkipFastPath)                 \
     322             :   V(ObjectGetOwnPropertyNames)                \
     323             :   V(ObjectGetOwnPropertyNamesTryFast)         \
     324             :   V(RegExpInitializeAndCompile)               \
     325             :   V(StackGuard)                               \
     326             :   V(StringAdd)                                \
     327             :   V(StringCharCodeAt)                         \
     328             :   V(StringEqual)                              \
     329             :   V(StringIndexOfUnchecked)                   \
     330             :   V(StringParseFloat)                         \
     331             :   V(StringParseInt)                           \
     332             :   V(SymbolDescriptiveString)                  \
     333             :   V(ThrowRangeError)                          \
     334             :   V(ThrowTypeError)                           \
     335             :   V(ToName)                                   \
     336             :   V(TransitionElementsKind)                   \
     337             :   /* Misc. */                                 \
     338             :   V(Call)                                     \
     339             :   V(CompleteInobjectSlackTrackingForMap)      \
     340             :   V(HasInPrototypeChain)                      \
     341             :   V(IncrementUseCounter)                      \
     342             :   V(MaxSmi)                                   \
     343             :   V(NewObject)                                \
     344             :   V(SmiLexicographicCompare)                  \
     345             :   V(StringMaxLength)                          \
     346             :   V(StringToArray)                            \
     347             :   /* Test */                                  \
     348             :   V(GetOptimizationStatus)                    \
     349             :   V(OptimizeFunctionOnNextCall)               \
     350             :   V(OptimizeOsr)                              \
     351             :   V(UnblockConcurrentRecompilation)
     352             : 
     353             : // Intrinsics with inline versions have to be whitelisted here a second time.
     354             : #define INLINE_INTRINSIC_WHITELIST(V) \
     355             :   V(Call)                             \
     356             :   V(IsJSReceiver)
     357             : 
     358             : #define CASE(Name) case Runtime::k##Name:
     359             : #define INLINE_CASE(Name) case Runtime::kInline##Name:
     360        1320 :   switch (id) {
     361             :     INTRINSIC_WHITELIST(CASE)
     362             :     INLINE_INTRINSIC_WHITELIST(INLINE_CASE)
     363             :     return true;
     364             :     default:
     365          63 :       if (FLAG_trace_side_effect_free_debug_evaluate) {
     366             :         PrintF("[debug-evaluate] intrinsic %s may cause side effect.\n",
     367           0 :                Runtime::FunctionForId(id)->name);
     368             :       }
     369             :       return false;
     370             :   }
     371             : 
     372             : #undef CASE
     373             : #undef INLINE_CASE
     374             : #undef INTRINSIC_WHITELIST
     375             : #undef INLINE_INTRINSIC_WHITELIST
     376             : }
     377             : 
     378       72163 : bool BytecodeHasNoSideEffect(interpreter::Bytecode bytecode) {
     379             :   typedef interpreter::Bytecode Bytecode;
     380             :   typedef interpreter::Bytecodes Bytecodes;
     381       72163 :   if (Bytecodes::IsWithoutExternalSideEffects(bytecode)) return true;
     382       34803 :   if (Bytecodes::IsCallOrConstruct(bytecode)) return true;
     383       29926 :   if (Bytecodes::IsJumpIfToBoolean(bytecode)) return true;
     384       29507 :   if (Bytecodes::IsPrefixScalingBytecode(bytecode)) return true;
     385       29507 :   switch (bytecode) {
     386             :     // Whitelist for bytecodes.
     387             :     // Loads.
     388             :     case Bytecode::kLdaLookupSlot:
     389             :     case Bytecode::kLdaGlobal:
     390             :     case Bytecode::kLdaNamedProperty:
     391             :     case Bytecode::kLdaNamedPropertyNoFeedback:
     392             :     case Bytecode::kLdaKeyedProperty:
     393             :     case Bytecode::kLdaGlobalInsideTypeof:
     394             :     case Bytecode::kLdaLookupSlotInsideTypeof:
     395             :     // Arithmetics.
     396             :     case Bytecode::kAdd:
     397             :     case Bytecode::kAddSmi:
     398             :     case Bytecode::kSub:
     399             :     case Bytecode::kSubSmi:
     400             :     case Bytecode::kMul:
     401             :     case Bytecode::kMulSmi:
     402             :     case Bytecode::kDiv:
     403             :     case Bytecode::kDivSmi:
     404             :     case Bytecode::kMod:
     405             :     case Bytecode::kModSmi:
     406             :     case Bytecode::kExp:
     407             :     case Bytecode::kExpSmi:
     408             :     case Bytecode::kNegate:
     409             :     case Bytecode::kBitwiseAnd:
     410             :     case Bytecode::kBitwiseAndSmi:
     411             :     case Bytecode::kBitwiseNot:
     412             :     case Bytecode::kBitwiseOr:
     413             :     case Bytecode::kBitwiseOrSmi:
     414             :     case Bytecode::kBitwiseXor:
     415             :     case Bytecode::kBitwiseXorSmi:
     416             :     case Bytecode::kShiftLeft:
     417             :     case Bytecode::kShiftLeftSmi:
     418             :     case Bytecode::kShiftRight:
     419             :     case Bytecode::kShiftRightSmi:
     420             :     case Bytecode::kShiftRightLogical:
     421             :     case Bytecode::kShiftRightLogicalSmi:
     422             :     case Bytecode::kInc:
     423             :     case Bytecode::kDec:
     424             :     case Bytecode::kLogicalNot:
     425             :     case Bytecode::kToBooleanLogicalNot:
     426             :     case Bytecode::kTypeOf:
     427             :     // Contexts.
     428             :     case Bytecode::kCreateBlockContext:
     429             :     case Bytecode::kCreateCatchContext:
     430             :     case Bytecode::kCreateFunctionContext:
     431             :     case Bytecode::kCreateEvalContext:
     432             :     case Bytecode::kCreateWithContext:
     433             :     // Literals.
     434             :     case Bytecode::kCreateArrayLiteral:
     435             :     case Bytecode::kCreateEmptyArrayLiteral:
     436             :     case Bytecode::kCreateArrayFromIterable:
     437             :     case Bytecode::kCreateObjectLiteral:
     438             :     case Bytecode::kCreateEmptyObjectLiteral:
     439             :     case Bytecode::kCreateRegExpLiteral:
     440             :     // Allocations.
     441             :     case Bytecode::kCreateClosure:
     442             :     case Bytecode::kCreateUnmappedArguments:
     443             :     case Bytecode::kCreateRestParameter:
     444             :     // Comparisons.
     445             :     case Bytecode::kTestEqual:
     446             :     case Bytecode::kTestEqualStrict:
     447             :     case Bytecode::kTestLessThan:
     448             :     case Bytecode::kTestLessThanOrEqual:
     449             :     case Bytecode::kTestGreaterThan:
     450             :     case Bytecode::kTestGreaterThanOrEqual:
     451             :     case Bytecode::kTestInstanceOf:
     452             :     case Bytecode::kTestIn:
     453             :     case Bytecode::kTestReferenceEqual:
     454             :     case Bytecode::kTestUndetectable:
     455             :     case Bytecode::kTestTypeOf:
     456             :     case Bytecode::kTestUndefined:
     457             :     case Bytecode::kTestNull:
     458             :     // Conversions.
     459             :     case Bytecode::kToObject:
     460             :     case Bytecode::kToName:
     461             :     case Bytecode::kToNumber:
     462             :     case Bytecode::kToNumeric:
     463             :     case Bytecode::kToString:
     464             :     // Misc.
     465             :     case Bytecode::kForInEnumerate:
     466             :     case Bytecode::kForInPrepare:
     467             :     case Bytecode::kForInContinue:
     468             :     case Bytecode::kForInNext:
     469             :     case Bytecode::kForInStep:
     470             :     case Bytecode::kThrow:
     471             :     case Bytecode::kReThrow:
     472             :     case Bytecode::kThrowReferenceErrorIfHole:
     473             :     case Bytecode::kThrowSuperNotCalledIfHole:
     474             :     case Bytecode::kThrowSuperAlreadyCalledIfNotHole:
     475             :     case Bytecode::kIllegal:
     476             :     case Bytecode::kCallJSRuntime:
     477             :     case Bytecode::kStackCheck:
     478             :     case Bytecode::kReturn:
     479             :     case Bytecode::kSetPendingMessage:
     480             :       return true;
     481             :     default:
     482        2446 :       return false;
     483             :   }
     484             : }
     485             : 
     486        6278 : DebugInfo::SideEffectState BuiltinGetSideEffectState(Builtins::Name id) {
     487        6278 :   switch (id) {
     488             :     // Whitelist for builtins.
     489             :     // Object builtins.
     490             :     case Builtins::kObjectConstructor:
     491             :     case Builtins::kObjectCreate:
     492             :     case Builtins::kObjectEntries:
     493             :     case Builtins::kObjectGetOwnPropertyDescriptor:
     494             :     case Builtins::kObjectGetOwnPropertyDescriptors:
     495             :     case Builtins::kObjectGetOwnPropertyNames:
     496             :     case Builtins::kObjectGetOwnPropertySymbols:
     497             :     case Builtins::kObjectGetPrototypeOf:
     498             :     case Builtins::kObjectIs:
     499             :     case Builtins::kObjectIsExtensible:
     500             :     case Builtins::kObjectIsFrozen:
     501             :     case Builtins::kObjectIsSealed:
     502             :     case Builtins::kObjectPrototypeValueOf:
     503             :     case Builtins::kObjectValues:
     504             :     case Builtins::kObjectPrototypeHasOwnProperty:
     505             :     case Builtins::kObjectPrototypeIsPrototypeOf:
     506             :     case Builtins::kObjectPrototypePropertyIsEnumerable:
     507             :     case Builtins::kObjectPrototypeToString:
     508             :     // Array builtins.
     509             :     case Builtins::kArrayIsArray:
     510             :     case Builtins::kArrayConstructor:
     511             :     case Builtins::kArrayIndexOf:
     512             :     case Builtins::kArrayPrototypeValues:
     513             :     case Builtins::kArrayIncludes:
     514             :     case Builtins::kArrayPrototypeEntries:
     515             :     case Builtins::kArrayPrototypeFill:
     516             :     case Builtins::kArrayPrototypeFind:
     517             :     case Builtins::kArrayPrototypeFindIndex:
     518             :     case Builtins::kArrayPrototypeFlat:
     519             :     case Builtins::kArrayPrototypeFlatMap:
     520             :     case Builtins::kArrayPrototypeJoin:
     521             :     case Builtins::kArrayPrototypeKeys:
     522             :     case Builtins::kArrayPrototypeLastIndexOf:
     523             :     case Builtins::kArrayPrototypeSlice:
     524             :     case Builtins::kArrayPrototypeSort:
     525             :     case Builtins::kArrayPrototypeToLocaleString:
     526             :     case Builtins::kArrayPrototypeToString:
     527             :     case Builtins::kArrayForEach:
     528             :     case Builtins::kArrayEvery:
     529             :     case Builtins::kArraySome:
     530             :     case Builtins::kArrayConcat:
     531             :     case Builtins::kArrayFilter:
     532             :     case Builtins::kArrayMap:
     533             :     case Builtins::kArrayReduce:
     534             :     case Builtins::kArrayReduceRight:
     535             :     // Trace builtins.
     536             :     case Builtins::kIsTraceCategoryEnabled:
     537             :     case Builtins::kTrace:
     538             :     // TypedArray builtins.
     539             :     case Builtins::kTypedArrayConstructor:
     540             :     case Builtins::kTypedArrayPrototypeBuffer:
     541             :     case Builtins::kTypedArrayPrototypeByteLength:
     542             :     case Builtins::kTypedArrayPrototypeByteOffset:
     543             :     case Builtins::kTypedArrayPrototypeLength:
     544             :     case Builtins::kTypedArrayPrototypeEntries:
     545             :     case Builtins::kTypedArrayPrototypeKeys:
     546             :     case Builtins::kTypedArrayPrototypeValues:
     547             :     case Builtins::kTypedArrayPrototypeFind:
     548             :     case Builtins::kTypedArrayPrototypeFindIndex:
     549             :     case Builtins::kTypedArrayPrototypeIncludes:
     550             :     case Builtins::kTypedArrayPrototypeIndexOf:
     551             :     case Builtins::kTypedArrayPrototypeLastIndexOf:
     552             :     case Builtins::kTypedArrayPrototypeSlice:
     553             :     case Builtins::kTypedArrayPrototypeSubArray:
     554             :     case Builtins::kTypedArrayPrototypeEvery:
     555             :     case Builtins::kTypedArrayPrototypeSome:
     556             :     case Builtins::kTypedArrayPrototypeFilter:
     557             :     case Builtins::kTypedArrayPrototypeMap:
     558             :     case Builtins::kTypedArrayPrototypeReduce:
     559             :     case Builtins::kTypedArrayPrototypeReduceRight:
     560             :     case Builtins::kTypedArrayPrototypeForEach:
     561             :     // ArrayBuffer builtins.
     562             :     case Builtins::kArrayBufferConstructor:
     563             :     case Builtins::kArrayBufferPrototypeGetByteLength:
     564             :     case Builtins::kArrayBufferIsView:
     565             :     case Builtins::kArrayBufferPrototypeSlice:
     566             :     case Builtins::kReturnReceiver:
     567             :     // DataView builtins.
     568             :     case Builtins::kDataViewConstructor:
     569             :     case Builtins::kDataViewPrototypeGetBuffer:
     570             :     case Builtins::kDataViewPrototypeGetByteLength:
     571             :     case Builtins::kDataViewPrototypeGetByteOffset:
     572             :     case Builtins::kDataViewPrototypeGetInt8:
     573             :     case Builtins::kDataViewPrototypeGetUint8:
     574             :     case Builtins::kDataViewPrototypeGetInt16:
     575             :     case Builtins::kDataViewPrototypeGetUint16:
     576             :     case Builtins::kDataViewPrototypeGetInt32:
     577             :     case Builtins::kDataViewPrototypeGetUint32:
     578             :     case Builtins::kDataViewPrototypeGetFloat32:
     579             :     case Builtins::kDataViewPrototypeGetFloat64:
     580             :     case Builtins::kDataViewPrototypeGetBigInt64:
     581             :     case Builtins::kDataViewPrototypeGetBigUint64:
     582             :     // Boolean bulitins.
     583             :     case Builtins::kBooleanConstructor:
     584             :     case Builtins::kBooleanPrototypeToString:
     585             :     case Builtins::kBooleanPrototypeValueOf:
     586             :     // Date builtins.
     587             :     case Builtins::kDateConstructor:
     588             :     case Builtins::kDateNow:
     589             :     case Builtins::kDateParse:
     590             :     case Builtins::kDatePrototypeGetDate:
     591             :     case Builtins::kDatePrototypeGetDay:
     592             :     case Builtins::kDatePrototypeGetFullYear:
     593             :     case Builtins::kDatePrototypeGetHours:
     594             :     case Builtins::kDatePrototypeGetMilliseconds:
     595             :     case Builtins::kDatePrototypeGetMinutes:
     596             :     case Builtins::kDatePrototypeGetMonth:
     597             :     case Builtins::kDatePrototypeGetSeconds:
     598             :     case Builtins::kDatePrototypeGetTime:
     599             :     case Builtins::kDatePrototypeGetTimezoneOffset:
     600             :     case Builtins::kDatePrototypeGetUTCDate:
     601             :     case Builtins::kDatePrototypeGetUTCDay:
     602             :     case Builtins::kDatePrototypeGetUTCFullYear:
     603             :     case Builtins::kDatePrototypeGetUTCHours:
     604             :     case Builtins::kDatePrototypeGetUTCMilliseconds:
     605             :     case Builtins::kDatePrototypeGetUTCMinutes:
     606             :     case Builtins::kDatePrototypeGetUTCMonth:
     607             :     case Builtins::kDatePrototypeGetUTCSeconds:
     608             :     case Builtins::kDatePrototypeGetYear:
     609             :     case Builtins::kDatePrototypeToDateString:
     610             :     case Builtins::kDatePrototypeToISOString:
     611             :     case Builtins::kDatePrototypeToUTCString:
     612             :     case Builtins::kDatePrototypeToString:
     613             :     case Builtins::kDatePrototypeToTimeString:
     614             :     case Builtins::kDatePrototypeToJson:
     615             :     case Builtins::kDatePrototypeToPrimitive:
     616             :     case Builtins::kDatePrototypeValueOf:
     617             :     // Map builtins.
     618             :     case Builtins::kMapConstructor:
     619             :     case Builtins::kMapPrototypeForEach:
     620             :     case Builtins::kMapPrototypeGet:
     621             :     case Builtins::kMapPrototypeHas:
     622             :     case Builtins::kMapPrototypeEntries:
     623             :     case Builtins::kMapPrototypeGetSize:
     624             :     case Builtins::kMapPrototypeKeys:
     625             :     case Builtins::kMapPrototypeValues:
     626             :     // WeakMap builtins.
     627             :     case Builtins::kWeakMapConstructor:
     628             :     case Builtins::kWeakMapGet:
     629             :     case Builtins::kWeakMapHas:
     630             :     // Math builtins.
     631             :     case Builtins::kMathAbs:
     632             :     case Builtins::kMathAcos:
     633             :     case Builtins::kMathAcosh:
     634             :     case Builtins::kMathAsin:
     635             :     case Builtins::kMathAsinh:
     636             :     case Builtins::kMathAtan:
     637             :     case Builtins::kMathAtanh:
     638             :     case Builtins::kMathAtan2:
     639             :     case Builtins::kMathCeil:
     640             :     case Builtins::kMathCbrt:
     641             :     case Builtins::kMathExpm1:
     642             :     case Builtins::kMathClz32:
     643             :     case Builtins::kMathCos:
     644             :     case Builtins::kMathCosh:
     645             :     case Builtins::kMathExp:
     646             :     case Builtins::kMathFloor:
     647             :     case Builtins::kMathFround:
     648             :     case Builtins::kMathHypot:
     649             :     case Builtins::kMathImul:
     650             :     case Builtins::kMathLog:
     651             :     case Builtins::kMathLog1p:
     652             :     case Builtins::kMathLog2:
     653             :     case Builtins::kMathLog10:
     654             :     case Builtins::kMathMax:
     655             :     case Builtins::kMathMin:
     656             :     case Builtins::kMathPow:
     657             :     case Builtins::kMathRandom:
     658             :     case Builtins::kMathRound:
     659             :     case Builtins::kMathSign:
     660             :     case Builtins::kMathSin:
     661             :     case Builtins::kMathSinh:
     662             :     case Builtins::kMathSqrt:
     663             :     case Builtins::kMathTan:
     664             :     case Builtins::kMathTanh:
     665             :     case Builtins::kMathTrunc:
     666             :     // Number builtins.
     667             :     case Builtins::kNumberConstructor:
     668             :     case Builtins::kNumberIsFinite:
     669             :     case Builtins::kNumberIsInteger:
     670             :     case Builtins::kNumberIsNaN:
     671             :     case Builtins::kNumberIsSafeInteger:
     672             :     case Builtins::kNumberParseFloat:
     673             :     case Builtins::kNumberParseInt:
     674             :     case Builtins::kNumberPrototypeToExponential:
     675             :     case Builtins::kNumberPrototypeToFixed:
     676             :     case Builtins::kNumberPrototypeToPrecision:
     677             :     case Builtins::kNumberPrototypeToString:
     678             :     case Builtins::kNumberPrototypeValueOf:
     679             :     // BigInt builtins.
     680             :     case Builtins::kBigIntConstructor:
     681             :     case Builtins::kBigIntAsIntN:
     682             :     case Builtins::kBigIntAsUintN:
     683             :     case Builtins::kBigIntPrototypeToString:
     684             :     case Builtins::kBigIntPrototypeValueOf:
     685             :     // Set builtins.
     686             :     case Builtins::kSetConstructor:
     687             :     case Builtins::kSetPrototypeEntries:
     688             :     case Builtins::kSetPrototypeForEach:
     689             :     case Builtins::kSetPrototypeGetSize:
     690             :     case Builtins::kSetPrototypeHas:
     691             :     case Builtins::kSetPrototypeValues:
     692             :     // WeakSet builtins.
     693             :     case Builtins::kWeakSetConstructor:
     694             :     case Builtins::kWeakSetHas:
     695             :     // String builtins. Strings are immutable.
     696             :     case Builtins::kStringFromCharCode:
     697             :     case Builtins::kStringFromCodePoint:
     698             :     case Builtins::kStringConstructor:
     699             :     case Builtins::kStringPrototypeAnchor:
     700             :     case Builtins::kStringPrototypeBig:
     701             :     case Builtins::kStringPrototypeBlink:
     702             :     case Builtins::kStringPrototypeBold:
     703             :     case Builtins::kStringPrototypeCharAt:
     704             :     case Builtins::kStringPrototypeCharCodeAt:
     705             :     case Builtins::kStringPrototypeCodePointAt:
     706             :     case Builtins::kStringPrototypeConcat:
     707             :     case Builtins::kStringPrototypeEndsWith:
     708             :     case Builtins::kStringPrototypeFixed:
     709             :     case Builtins::kStringPrototypeFontcolor:
     710             :     case Builtins::kStringPrototypeFontsize:
     711             :     case Builtins::kStringPrototypeIncludes:
     712             :     case Builtins::kStringPrototypeIndexOf:
     713             :     case Builtins::kStringPrototypeItalics:
     714             :     case Builtins::kStringPrototypeLastIndexOf:
     715             :     case Builtins::kStringPrototypeLink:
     716             :     case Builtins::kStringPrototypeMatchAll:
     717             :     case Builtins::kStringPrototypePadEnd:
     718             :     case Builtins::kStringPrototypePadStart:
     719             :     case Builtins::kStringPrototypeRepeat:
     720             :     case Builtins::kStringPrototypeSlice:
     721             :     case Builtins::kStringPrototypeSmall:
     722             :     case Builtins::kStringPrototypeStartsWith:
     723             :     case Builtins::kStringPrototypeStrike:
     724             :     case Builtins::kStringPrototypeSub:
     725             :     case Builtins::kStringPrototypeSubstr:
     726             :     case Builtins::kStringPrototypeSubstring:
     727             :     case Builtins::kStringPrototypeSup:
     728             :     case Builtins::kStringPrototypeToString:
     729             : #ifndef V8_INTL_SUPPORT
     730             :     case Builtins::kStringPrototypeToLowerCase:
     731             :     case Builtins::kStringPrototypeToUpperCase:
     732             : #endif
     733             :     case Builtins::kStringPrototypeTrim:
     734             :     case Builtins::kStringPrototypeTrimEnd:
     735             :     case Builtins::kStringPrototypeTrimStart:
     736             :     case Builtins::kStringPrototypeValueOf:
     737             :     case Builtins::kStringToNumber:
     738             :     case Builtins::kStringSubstring:
     739             :     // Symbol builtins.
     740             :     case Builtins::kSymbolConstructor:
     741             :     case Builtins::kSymbolKeyFor:
     742             :     case Builtins::kSymbolPrototypeToString:
     743             :     case Builtins::kSymbolPrototypeValueOf:
     744             :     case Builtins::kSymbolPrototypeToPrimitive:
     745             :     // JSON builtins.
     746             :     case Builtins::kJsonParse:
     747             :     case Builtins::kJsonStringify:
     748             :     // Global function builtins.
     749             :     case Builtins::kGlobalDecodeURI:
     750             :     case Builtins::kGlobalDecodeURIComponent:
     751             :     case Builtins::kGlobalEncodeURI:
     752             :     case Builtins::kGlobalEncodeURIComponent:
     753             :     case Builtins::kGlobalEscape:
     754             :     case Builtins::kGlobalUnescape:
     755             :     case Builtins::kGlobalIsFinite:
     756             :     case Builtins::kGlobalIsNaN:
     757             :     // Function builtins.
     758             :     case Builtins::kFunctionPrototypeToString:
     759             :     case Builtins::kFunctionPrototypeBind:
     760             :     case Builtins::kFastFunctionPrototypeBind:
     761             :     case Builtins::kFunctionPrototypeCall:
     762             :     case Builtins::kFunctionPrototypeApply:
     763             :     // Error builtins.
     764             :     case Builtins::kErrorConstructor:
     765             :     case Builtins::kMakeError:
     766             :     case Builtins::kMakeTypeError:
     767             :     case Builtins::kMakeSyntaxError:
     768             :     case Builtins::kMakeRangeError:
     769             :     case Builtins::kMakeURIError:
     770             :     // RegExp builtins.
     771             :     case Builtins::kRegExpConstructor:
     772             :     // Internal.
     773             :     case Builtins::kStrictPoisonPillThrower:
     774             :     case Builtins::kAllocateInNewSpace:
     775             :     case Builtins::kAllocateInOldSpace:
     776             :       return DebugInfo::kHasNoSideEffect;
     777             : 
     778             :     // Set builtins.
     779             :     case Builtins::kSetIteratorPrototypeNext:
     780             :     case Builtins::kSetPrototypeAdd:
     781             :     case Builtins::kSetPrototypeClear:
     782             :     case Builtins::kSetPrototypeDelete:
     783             :     // Array builtins.
     784             :     case Builtins::kArrayIteratorPrototypeNext:
     785             :     case Builtins::kArrayPrototypePop:
     786             :     case Builtins::kArrayPrototypePush:
     787             :     case Builtins::kArrayPrototypeReverse:
     788             :     case Builtins::kArrayPrototypeShift:
     789             :     case Builtins::kArrayPrototypeUnshift:
     790             :     case Builtins::kArrayPrototypeSplice:
     791             :     case Builtins::kArrayUnshift:
     792             :     // Map builtins.
     793             :     case Builtins::kMapIteratorPrototypeNext:
     794             :     case Builtins::kMapPrototypeClear:
     795             :     case Builtins::kMapPrototypeDelete:
     796             :     case Builtins::kMapPrototypeSet:
     797             :     // RegExp builtins.
     798             :     case Builtins::kRegExpPrototypeTest:
     799             :     case Builtins::kRegExpPrototypeExec:
     800             :     case Builtins::kRegExpPrototypeSplit:
     801             :     case Builtins::kRegExpPrototypeFlagsGetter:
     802             :     case Builtins::kRegExpPrototypeGlobalGetter:
     803             :     case Builtins::kRegExpPrototypeIgnoreCaseGetter:
     804             :     case Builtins::kRegExpPrototypeMatchAll:
     805             :     case Builtins::kRegExpPrototypeMultilineGetter:
     806             :     case Builtins::kRegExpPrototypeDotAllGetter:
     807             :     case Builtins::kRegExpPrototypeUnicodeGetter:
     808             :     case Builtins::kRegExpPrototypeStickyGetter:
     809         427 :       return DebugInfo::kRequiresRuntimeChecks;
     810             :     default:
     811        2037 :       if (FLAG_trace_side_effect_free_debug_evaluate) {
     812             :         PrintF("[debug-evaluate] built-in %s may cause side effect.\n",
     813           0 :                Builtins::name(id));
     814             :       }
     815             :       return DebugInfo::kHasSideEffects;
     816             :   }
     817             : }
     818             : 
     819             : bool BytecodeRequiresRuntimeCheck(interpreter::Bytecode bytecode) {
     820             :   typedef interpreter::Bytecode Bytecode;
     821             :   switch (bytecode) {
     822             :     case Bytecode::kStaNamedProperty:
     823             :     case Bytecode::kStaNamedPropertyNoFeedback:
     824             :     case Bytecode::kStaNamedOwnProperty:
     825             :     case Bytecode::kStaKeyedProperty:
     826             :     case Bytecode::kStaInArrayLiteral:
     827             :     case Bytecode::kStaDataPropertyInLiteral:
     828             :     case Bytecode::kStaCurrentContextSlot:
     829             :       return true;
     830             :     default:
     831             :       return false;
     832             :   }
     833             : }
     834             : 
     835             : }  // anonymous namespace
     836             : 
     837             : // static
     838       12188 : DebugInfo::SideEffectState DebugEvaluate::FunctionGetSideEffectState(
     839             :     Isolate* isolate, Handle<SharedFunctionInfo> info) {
     840       12188 :   if (FLAG_trace_side_effect_free_debug_evaluate) {
     841             :     PrintF("[debug-evaluate] Checking function %s for side effect.\n",
     842           0 :            info->DebugName()->ToCString().get());
     843             :   }
     844             : 
     845             :   DCHECK(info->is_compiled());
     846       12188 :   if (info->HasBytecodeArray()) {
     847             :     // Check bytecodes against whitelist.
     848       11462 :     Handle<BytecodeArray> bytecode_array(info->GetBytecodeArray(), isolate);
     849        5731 :     if (FLAG_trace_side_effect_free_debug_evaluate) {
     850           0 :       bytecode_array->Print();
     851             :     }
     852             :     bool requires_runtime_checks = false;
     853       84792 :     for (interpreter::BytecodeArrayIterator it(bytecode_array); !it.done();
     854       73330 :          it.Advance()) {
     855       73483 :       interpreter::Bytecode bytecode = it.current_bytecode();
     856             : 
     857       73483 :       if (interpreter::Bytecodes::IsCallRuntime(bytecode)) {
     858             :         Runtime::FunctionId id =
     859             :             (bytecode == interpreter::Bytecode::kInvokeIntrinsic)
     860             :                 ? it.GetIntrinsicIdOperand(0)
     861        1320 :                 : it.GetRuntimeIdOperand(0);
     862        1320 :         if (IntrinsicHasNoSideEffect(id)) continue;
     863         153 :         return DebugInfo::kHasSideEffects;
     864             :       }
     865             : 
     866       72163 :       if (BytecodeHasNoSideEffect(bytecode)) continue;
     867        2446 :       if (BytecodeRequiresRuntimeCheck(bytecode)) {
     868             :         requires_runtime_checks = true;
     869             :         continue;
     870             :       }
     871             : 
     872          90 :       if (FLAG_trace_side_effect_free_debug_evaluate) {
     873             :         PrintF("[debug-evaluate] bytecode %s may cause side effect.\n",
     874           0 :                interpreter::Bytecodes::ToString(bytecode));
     875             :       }
     876             : 
     877             :       // Did not match whitelist.
     878             :       return DebugInfo::kHasSideEffects;
     879             :     }
     880             :     return requires_runtime_checks ? DebugInfo::kRequiresRuntimeChecks
     881       11156 :                                    : DebugInfo::kHasNoSideEffect;
     882        6457 :   } else if (info->IsApiFunction()) {
     883         358 :     if (info->GetCode()->is_builtin()) {
     884         358 :       return info->GetCode()->builtin_index() == Builtins::kHandleApiCall
     885             :                  ? DebugInfo::kHasNoSideEffect
     886         179 :                  : DebugInfo::kHasSideEffects;
     887             :     }
     888             :   } else {
     889             :     // Check built-ins against whitelist.
     890             :     int builtin_index =
     891       12556 :         info->HasBuiltinId() ? info->builtin_id() : Builtins::kNoBuiltinId;
     892        6278 :     if (!Builtins::IsBuiltinId(builtin_index))
     893             :       return DebugInfo::kHasSideEffects;
     894             :     DebugInfo::SideEffectState state =
     895        6278 :         BuiltinGetSideEffectState(static_cast<Builtins::Name>(builtin_index));
     896        6278 :     return state;
     897             :   }
     898             : 
     899             :   return DebugInfo::kHasSideEffects;
     900             : }
     901             : 
     902             : #ifdef DEBUG
     903             : static bool TransitivelyCalledBuiltinHasNoSideEffect(Builtins::Name caller,
     904             :                                                      Builtins::Name callee) {
     905             :   switch (callee) {
     906             :       // Transitively called Builtins:
     907             :     case Builtins::kAbort:
     908             :     case Builtins::kAbortJS:
     909             :     case Builtins::kAdaptorWithBuiltinExitFrame:
     910             :     case Builtins::kArrayConstructorImpl:
     911             :     case Builtins::kArrayEveryLoopContinuation:
     912             :     case Builtins::kArrayFilterLoopContinuation:
     913             :     case Builtins::kArrayFindIndexLoopContinuation:
     914             :     case Builtins::kArrayFindLoopContinuation:
     915             :     case Builtins::kArrayForEachLoopContinuation:
     916             :     case Builtins::kArrayIncludesHoleyDoubles:
     917             :     case Builtins::kArrayIncludesPackedDoubles:
     918             :     case Builtins::kArrayIncludesSmiOrObject:
     919             :     case Builtins::kArrayIndexOfHoleyDoubles:
     920             :     case Builtins::kArrayIndexOfPackedDoubles:
     921             :     case Builtins::kArrayIndexOfSmiOrObject:
     922             :     case Builtins::kArrayMapLoopContinuation:
     923             :     case Builtins::kArrayReduceLoopContinuation:
     924             :     case Builtins::kArrayReduceRightLoopContinuation:
     925             :     case Builtins::kArraySomeLoopContinuation:
     926             :     case Builtins::kArrayTimSort:
     927             :     case Builtins::kCall_ReceiverIsAny:
     928             :     case Builtins::kCallWithArrayLike:
     929             :     case Builtins::kCEntry_Return1_DontSaveFPRegs_ArgvOnStack_NoBuiltinExit:
     930             :     case Builtins::kCEntry_Return1_DontSaveFPRegs_ArgvOnStack_BuiltinExit:
     931             :     case Builtins::kCEntry_Return1_DontSaveFPRegs_ArgvInRegister_NoBuiltinExit:
     932             :     case Builtins::kCEntry_Return1_SaveFPRegs_ArgvOnStack_NoBuiltinExit:
     933             :     case Builtins::kCEntry_Return1_SaveFPRegs_ArgvOnStack_BuiltinExit:
     934             :     case Builtins::kCEntry_Return2_DontSaveFPRegs_ArgvOnStack_NoBuiltinExit:
     935             :     case Builtins::kCEntry_Return2_DontSaveFPRegs_ArgvOnStack_BuiltinExit:
     936             :     case Builtins::kCEntry_Return2_DontSaveFPRegs_ArgvInRegister_NoBuiltinExit:
     937             :     case Builtins::kCEntry_Return2_SaveFPRegs_ArgvOnStack_NoBuiltinExit:
     938             :     case Builtins::kCEntry_Return2_SaveFPRegs_ArgvOnStack_BuiltinExit:
     939             :     case Builtins::kCloneFastJSArray:
     940             :     case Builtins::kConstruct:
     941             :     case Builtins::kConvertToLocaleString:
     942             :     case Builtins::kCreateTypedArray:
     943             :     case Builtins::kDirectCEntry:
     944             :     case Builtins::kDoubleToI:
     945             :     case Builtins::kExtractFastJSArray:
     946             :     case Builtins::kFastNewObject:
     947             :     case Builtins::kFindOrderedHashMapEntry:
     948             :     case Builtins::kFlatMapIntoArray:
     949             :     case Builtins::kFlattenIntoArray:
     950             :     case Builtins::kGetProperty:
     951             :     case Builtins::kHasProperty:
     952             :     case Builtins::kMathPowInternal:
     953             :     case Builtins::kNonNumberToNumber:
     954             :     case Builtins::kNonPrimitiveToPrimitive_Number:
     955             :     case Builtins::kNumberToString:
     956             :     case Builtins::kObjectToString:
     957             :     case Builtins::kOrderedHashTableHealIndex:
     958             :     case Builtins::kOrdinaryToPrimitive_Number:
     959             :     case Builtins::kOrdinaryToPrimitive_String:
     960             :     case Builtins::kParseInt:
     961             :     case Builtins::kProxyHasProperty:
     962             :     case Builtins::kRecordWrite:
     963             :     case Builtins::kStringAdd_CheckNone:
     964             :     case Builtins::kStringEqual:
     965             :     case Builtins::kStringIndexOf:
     966             :     case Builtins::kStringRepeat:
     967             :     case Builtins::kToInteger:
     968             :     case Builtins::kToInteger_TruncateMinusZero:
     969             :     case Builtins::kToLength:
     970             :     case Builtins::kToName:
     971             :     case Builtins::kToObject:
     972             :     case Builtins::kToString:
     973             :     case Builtins::kWeakMapLookupHashIndex:
     974             :       return true;
     975             :     case Builtins::kJoinStackPop:
     976             :     case Builtins::kJoinStackPush:
     977             :       switch (caller) {
     978             :         case Builtins::kArrayPrototypeJoin:
     979             :         case Builtins::kArrayPrototypeToLocaleString:
     980             :           return true;
     981             :         default:
     982             :           return false;
     983             :       }
     984             :     case Builtins::kSetProperty:
     985             :       switch (caller) {
     986             :         case Builtins::kArrayPrototypeSlice:
     987             :         case Builtins::kTypedArrayPrototypeMap:
     988             :         case Builtins::kStringPrototypeMatchAll:
     989             :           return true;
     990             :         default:
     991             :           return false;
     992             :       }
     993             :     default:
     994             :       return false;
     995             :   }
     996             : }
     997             : 
     998             : // static
     999             : void DebugEvaluate::VerifyTransitiveBuiltins(Isolate* isolate) {
    1000             :   // TODO(yangguo): also check runtime calls.
    1001             :   bool failed = false;
    1002             :   bool sanity_check = false;
    1003             :   for (int i = 0; i < Builtins::builtin_count; i++) {
    1004             :     Builtins::Name caller = static_cast<Builtins::Name>(i);
    1005             :     DebugInfo::SideEffectState state = BuiltinGetSideEffectState(caller);
    1006             :     if (state != DebugInfo::kHasNoSideEffect) continue;
    1007             :     Code code = isolate->builtins()->builtin(caller);
    1008             :     int mode = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
    1009             :                RelocInfo::ModeMask(RelocInfo::RELATIVE_CODE_TARGET);
    1010             : 
    1011             :     for (RelocIterator it(code, mode); !it.done(); it.next()) {
    1012             :       RelocInfo* rinfo = it.rinfo();
    1013             :       DCHECK(RelocInfo::IsCodeTargetMode(rinfo->rmode()));
    1014             :       Code callee_code = isolate->heap()->GcSafeFindCodeForInnerPointer(
    1015             :           rinfo->target_address());
    1016             :       if (!callee_code->is_builtin()) continue;
    1017             :       Builtins::Name callee =
    1018             :           static_cast<Builtins::Name>(callee_code->builtin_index());
    1019             :       if (BuiltinGetSideEffectState(callee) == DebugInfo::kHasNoSideEffect) {
    1020             :         continue;
    1021             :       }
    1022             :       if (TransitivelyCalledBuiltinHasNoSideEffect(caller, callee)) {
    1023             :         sanity_check = true;
    1024             :         continue;
    1025             :       }
    1026             :       PrintF("Whitelisted builtin %s calls non-whitelisted builtin %s\n",
    1027             :              Builtins::name(caller), Builtins::name(callee));
    1028             :       failed = true;
    1029             :     }
    1030             :   }
    1031             :   CHECK(!failed);
    1032             : #if defined(V8_TARGET_ARCH_PPC) || defined(V8_TARGET_ARCH_MIPS64)
    1033             :   // Isolate-independent builtin calls and jumps do not emit reloc infos
    1034             :   // on PPC. We try to avoid using PC relative code due to performance
    1035             :   // issue with especially older hardwares.
    1036             :   // MIPS64 doesn't have PC relative code currently.
    1037             :   // TODO(mips): Add PC relative code to MIPS64.
    1038             :   USE(sanity_check);
    1039             : #else
    1040             :   CHECK(sanity_check);
    1041             : #endif
    1042             : }
    1043             : #endif  // DEBUG
    1044             : 
    1045             : // static
    1046        6761 : void DebugEvaluate::ApplySideEffectChecks(
    1047             :     Handle<BytecodeArray> bytecode_array) {
    1048      150798 :   for (interpreter::BytecodeArrayIterator it(bytecode_array); !it.done();
    1049      137276 :        it.Advance()) {
    1050      137276 :     interpreter::Bytecode bytecode = it.current_bytecode();
    1051      137276 :     if (BytecodeRequiresRuntimeCheck(bytecode)) it.ApplyDebugBreak();
    1052             :   }
    1053        6761 : }
    1054             : 
    1055             : }  // namespace internal
    1056      183867 : }  // namespace v8

Generated by: LCOV version 1.10