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 10368 : 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 8804 : 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 8804 : ScriptCompiler::kNoCacheNoReason, NOT_NATIVES_CODE);
38 :
39 : Handle<SharedFunctionInfo> shared_info;
40 8804 : if (!maybe_function_info.ToHandle(&shared_info)) return MaybeHandle<Object>();
41 :
42 : Handle<JSFunction> fun =
43 : isolate->factory()->NewFunctionFromSharedFunctionInfo(shared_info,
44 8754 : context);
45 9536 : if (throw_on_side_effect) isolate->debug()->StartSideEffectCheckMode();
46 : MaybeHandle<Object> result = Execution::Call(
47 17508 : isolate, fun, Handle<JSObject>(context->global_proxy(), isolate), 0,
48 17508 : nullptr);
49 9536 : if (throw_on_side_effect) isolate->debug()->StopSideEffectCheckMode();
50 8754 : return result;
51 : }
52 :
53 11949 : 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 11949 : StackTraceFrameIterator it(isolate, frame_id);
63 11949 : 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 23898 : ContextBuilder context_builder(isolate, frame, inlined_jsframe_index);
73 11949 : if (isolate->has_pending_exception()) return MaybeHandle<Object>();
74 :
75 : Handle<Context> context = context_builder.evaluation_context();
76 23898 : Handle<JSObject> receiver(context->global_proxy(), isolate);
77 : MaybeHandle<Object> maybe_result =
78 : Evaluate(isolate, context_builder.outer_info(), context, receiver, source,
79 23898 : throw_on_side_effect);
80 11949 : if (!maybe_result.is_null()) context_builder.UpdateValues();
81 11949 : 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 12034 : MaybeHandle<Object> DebugEvaluate::Evaluate(
129 8290 : 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 24068 : 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 16109 : if (throw_on_side_effect) isolate->debug()->StartSideEffectCheckMode();
144 11964 : success = Execution::Call(isolate, eval_fun, receiver, 0, nullptr)
145 23928 : .ToHandle(&result);
146 16109 : if (throw_on_side_effect) isolate->debug()->StopSideEffectCheckMode();
147 : if (!success) DCHECK(isolate->has_pending_exception());
148 13113 : return success ? result : MaybeHandle<Object>();
149 : }
150 :
151 11949 : Handle<SharedFunctionInfo> DebugEvaluate::ContextBuilder::outer_info() const {
152 35847 : return handle(frame_inspector_.GetFunction()->shared(), isolate_);
153 : }
154 :
155 11949 : 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 11949 : ScopeIterator::COLLECT_NON_LOCALS) {
162 : Handle<Context> outer_context(frame_inspector_.GetFunction()->context(),
163 23898 : isolate);
164 11949 : evaluation_context_ = outer_context;
165 : Factory* factory = isolate->factory();
166 :
167 23898 : 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 36677 : for (; scope_iterator_.InInnerScope(); scope_iterator_.Next()) {
186 12448 : ScopeIterator::ScopeType scope_type = scope_iterator_.Type();
187 12448 : if (scope_type == ScopeIterator::ScopeTypeScript) break;
188 : ContextChainElement context_chain_element;
189 13169 : if (scope_type == ScopeIterator::ScopeTypeLocal ||
190 799 : scope_iterator_.DeclaresLocals(ScopeIterator::Mode::STACK)) {
191 : context_chain_element.materialized_object =
192 12038 : scope_iterator_.ScopeObject(ScopeIterator::Mode::STACK);
193 : }
194 12370 : if (scope_iterator_.HasContext()) {
195 1064 : context_chain_element.wrapped_context = scope_iterator_.CurrentContext();
196 : }
197 12370 : if (scope_type == ScopeIterator::ScopeTypeLocal) {
198 11571 : context_chain_element.whitelist = scope_iterator_.GetNonLocals();
199 : }
200 12370 : context_chain_.push_back(context_chain_element);
201 : }
202 :
203 : Handle<ScopeInfo> scope_info =
204 23874 : evaluation_context_->IsNativeContext()
205 : ? Handle<ScopeInfo>::null()
206 25768 : : handle(evaluation_context_->scope_info(), isolate);
207 24307 : for (auto rit = context_chain_.rbegin(); rit != context_chain_.rend();
208 : rit++) {
209 12370 : ContextChainElement element = *rit;
210 12370 : scope_info = ScopeInfo::CreateForWithScope(isolate, scope_info);
211 12370 : scope_info->SetIsDebugEvaluateScope();
212 : evaluation_context_ = factory->NewDebugEvaluateContext(
213 : evaluation_context_, scope_info, element.materialized_object,
214 12370 : element.wrapped_context, element.whitelist);
215 : }
216 : }
217 :
218 :
219 10730 : void DebugEvaluate::ContextBuilder::UpdateValues() {
220 10730 : scope_iterator_.Restart();
221 32635 : for (ContextChainElement& element : context_chain_) {
222 11175 : if (!element.materialized_object.is_null()) {
223 : Handle<FixedArray> keys =
224 : KeyAccumulator::GetKeys(element.materialized_object,
225 : KeyCollectionMode::kOwnOnly,
226 10843 : ENUMERABLE_STRINGS)
227 21686 : .ToHandleChecked();
228 :
229 187882 : for (int i = 0; i < keys->length(); i++) {
230 : DCHECK(keys->get(i)->IsString());
231 83098 : Handle<String> key(String::cast(keys->get(i)), isolate_);
232 : Handle<Object> value =
233 83098 : JSReceiver::GetDataProperty(element.materialized_object, key);
234 83098 : scope_iterator_.SetVariableValue(key, value);
235 : }
236 : }
237 11175 : scope_iterator_.Next();
238 : }
239 10730 : }
240 :
241 : namespace {
242 :
243 1319 : 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(StringIncludes) \
287 : V(StringIndexOf) \
288 : V(StringReplaceOneCharWithString) \
289 : V(StringSubstring) \
290 : V(StringToNumber) \
291 : V(StringTrim) \
292 : /* BigInts */ \
293 : V(BigIntEqualToBigInt) \
294 : V(BigIntToBoolean) \
295 : V(BigIntToNumber) \
296 : /* Literals */ \
297 : V(CreateArrayLiteral) \
298 : V(CreateArrayLiteralWithoutAllocationSite) \
299 : V(CreateObjectLiteral) \
300 : V(CreateObjectLiteralWithoutAllocationSite) \
301 : V(CreateRegExpLiteral) \
302 : /* Called from builtins */ \
303 : V(AllocateInNewSpace) \
304 : V(AllocateInTargetSpace) \
305 : V(AllocateSeqOneByteString) \
306 : V(AllocateSeqTwoByteString) \
307 : V(ArrayIncludes_Slow) \
308 : V(ArrayIndexOf) \
309 : V(ArrayIsArray) \
310 : V(ClassOf) \
311 : V(GetFunctionName) \
312 : V(GetOwnPropertyDescriptor) \
313 : V(GlobalPrint) \
314 : V(HasProperty) \
315 : V(ObjectCreate) \
316 : V(ObjectEntries) \
317 : V(ObjectEntriesSkipFastPath) \
318 : V(ObjectHasOwnProperty) \
319 : V(ObjectValues) \
320 : V(ObjectValuesSkipFastPath) \
321 : V(ObjectGetOwnPropertyNames) \
322 : V(ObjectGetOwnPropertyNamesTryFast) \
323 : V(RegExpInitializeAndCompile) \
324 : V(StackGuard) \
325 : V(StringAdd) \
326 : V(StringCharCodeAt) \
327 : V(StringEqual) \
328 : V(StringIndexOfUnchecked) \
329 : V(StringParseFloat) \
330 : V(StringParseInt) \
331 : V(SymbolDescriptiveString) \
332 : V(ThrowRangeError) \
333 : V(ThrowTypeError) \
334 : V(ToName) \
335 : V(TransitionElementsKind) \
336 : /* Misc. */ \
337 : V(Call) \
338 : V(CompleteInobjectSlackTrackingForMap) \
339 : V(HasInPrototypeChain) \
340 : V(IncrementUseCounter) \
341 : V(MaxSmi) \
342 : V(NewObject) \
343 : V(SmiLexicographicCompare) \
344 : V(StringMaxLength) \
345 : V(StringToArray) \
346 : /* Test */ \
347 : V(GetOptimizationStatus) \
348 : V(OptimizeFunctionOnNextCall) \
349 : V(OptimizeOsr) \
350 : V(UnblockConcurrentRecompilation)
351 :
352 : // Intrinsics with inline versions have to be whitelisted here a second time.
353 : #define INLINE_INTRINSIC_WHITELIST(V) \
354 : V(Call) \
355 : V(IsJSReceiver)
356 :
357 : #define CASE(Name) case Runtime::k##Name:
358 : #define INLINE_CASE(Name) case Runtime::kInline##Name:
359 1319 : switch (id) {
360 : INTRINSIC_WHITELIST(CASE)
361 : INLINE_INTRINSIC_WHITELIST(INLINE_CASE)
362 : return true;
363 : default:
364 63 : if (FLAG_trace_side_effect_free_debug_evaluate) {
365 : PrintF("[debug-evaluate] intrinsic %s may cause side effect.\n",
366 0 : Runtime::FunctionForId(id)->name);
367 : }
368 : return false;
369 : }
370 :
371 : #undef CASE
372 : #undef INLINE_CASE
373 : #undef INTRINSIC_WHITELIST
374 : #undef INLINE_INTRINSIC_WHITELIST
375 : }
376 :
377 72133 : bool BytecodeHasNoSideEffect(interpreter::Bytecode bytecode) {
378 : typedef interpreter::Bytecode Bytecode;
379 : typedef interpreter::Bytecodes Bytecodes;
380 72133 : if (Bytecodes::IsWithoutExternalSideEffects(bytecode)) return true;
381 34787 : if (Bytecodes::IsCallOrConstruct(bytecode)) return true;
382 29911 : if (Bytecodes::IsJumpIfToBoolean(bytecode)) return true;
383 29492 : if (Bytecodes::IsPrefixScalingBytecode(bytecode)) return true;
384 29492 : switch (bytecode) {
385 : // Whitelist for bytecodes.
386 : // Loads.
387 : case Bytecode::kLdaLookupSlot:
388 : case Bytecode::kLdaGlobal:
389 : case Bytecode::kLdaNamedProperty:
390 : case Bytecode::kLdaNamedPropertyNoFeedback:
391 : case Bytecode::kLdaKeyedProperty:
392 : case Bytecode::kLdaGlobalInsideTypeof:
393 : case Bytecode::kLdaLookupSlotInsideTypeof:
394 : // Arithmetics.
395 : case Bytecode::kAdd:
396 : case Bytecode::kAddSmi:
397 : case Bytecode::kSub:
398 : case Bytecode::kSubSmi:
399 : case Bytecode::kMul:
400 : case Bytecode::kMulSmi:
401 : case Bytecode::kDiv:
402 : case Bytecode::kDivSmi:
403 : case Bytecode::kMod:
404 : case Bytecode::kModSmi:
405 : case Bytecode::kExp:
406 : case Bytecode::kExpSmi:
407 : case Bytecode::kNegate:
408 : case Bytecode::kBitwiseAnd:
409 : case Bytecode::kBitwiseAndSmi:
410 : case Bytecode::kBitwiseNot:
411 : case Bytecode::kBitwiseOr:
412 : case Bytecode::kBitwiseOrSmi:
413 : case Bytecode::kBitwiseXor:
414 : case Bytecode::kBitwiseXorSmi:
415 : case Bytecode::kShiftLeft:
416 : case Bytecode::kShiftLeftSmi:
417 : case Bytecode::kShiftRight:
418 : case Bytecode::kShiftRightSmi:
419 : case Bytecode::kShiftRightLogical:
420 : case Bytecode::kShiftRightLogicalSmi:
421 : case Bytecode::kInc:
422 : case Bytecode::kDec:
423 : case Bytecode::kLogicalNot:
424 : case Bytecode::kToBooleanLogicalNot:
425 : case Bytecode::kTypeOf:
426 : // Contexts.
427 : case Bytecode::kCreateBlockContext:
428 : case Bytecode::kCreateCatchContext:
429 : case Bytecode::kCreateFunctionContext:
430 : case Bytecode::kCreateEvalContext:
431 : case Bytecode::kCreateWithContext:
432 : // Literals.
433 : case Bytecode::kCreateArrayLiteral:
434 : case Bytecode::kCreateEmptyArrayLiteral:
435 : case Bytecode::kCreateArrayFromIterable:
436 : case Bytecode::kCreateObjectLiteral:
437 : case Bytecode::kCreateEmptyObjectLiteral:
438 : case Bytecode::kCreateRegExpLiteral:
439 : // Allocations.
440 : case Bytecode::kCreateClosure:
441 : case Bytecode::kCreateUnmappedArguments:
442 : case Bytecode::kCreateRestParameter:
443 : // Comparisons.
444 : case Bytecode::kTestEqual:
445 : case Bytecode::kTestEqualStrict:
446 : case Bytecode::kTestLessThan:
447 : case Bytecode::kTestLessThanOrEqual:
448 : case Bytecode::kTestGreaterThan:
449 : case Bytecode::kTestGreaterThanOrEqual:
450 : case Bytecode::kTestInstanceOf:
451 : case Bytecode::kTestIn:
452 : case Bytecode::kTestReferenceEqual:
453 : case Bytecode::kTestUndetectable:
454 : case Bytecode::kTestTypeOf:
455 : case Bytecode::kTestUndefined:
456 : case Bytecode::kTestNull:
457 : // Conversions.
458 : case Bytecode::kToObject:
459 : case Bytecode::kToName:
460 : case Bytecode::kToNumber:
461 : case Bytecode::kToNumeric:
462 : case Bytecode::kToString:
463 : // Misc.
464 : case Bytecode::kForInEnumerate:
465 : case Bytecode::kForInPrepare:
466 : case Bytecode::kForInContinue:
467 : case Bytecode::kForInNext:
468 : case Bytecode::kForInStep:
469 : case Bytecode::kThrow:
470 : case Bytecode::kReThrow:
471 : case Bytecode::kThrowReferenceErrorIfHole:
472 : case Bytecode::kThrowSuperNotCalledIfHole:
473 : case Bytecode::kThrowSuperAlreadyCalledIfNotHole:
474 : case Bytecode::kIllegal:
475 : case Bytecode::kCallJSRuntime:
476 : case Bytecode::kStackCheck:
477 : case Bytecode::kReturn:
478 : case Bytecode::kSetPendingMessage:
479 : return true;
480 : default:
481 2446 : return false;
482 : }
483 : }
484 :
485 6272 : DebugInfo::SideEffectState BuiltinGetSideEffectState(Builtins::Name id) {
486 6272 : switch (id) {
487 : // Whitelist for builtins.
488 : // Object builtins.
489 : case Builtins::kObjectConstructor:
490 : case Builtins::kObjectCreate:
491 : case Builtins::kObjectEntries:
492 : case Builtins::kObjectGetOwnPropertyDescriptor:
493 : case Builtins::kObjectGetOwnPropertyDescriptors:
494 : case Builtins::kObjectGetOwnPropertyNames:
495 : case Builtins::kObjectGetOwnPropertySymbols:
496 : case Builtins::kObjectGetPrototypeOf:
497 : case Builtins::kObjectIs:
498 : case Builtins::kObjectIsExtensible:
499 : case Builtins::kObjectIsFrozen:
500 : case Builtins::kObjectIsSealed:
501 : case Builtins::kObjectPrototypeValueOf:
502 : case Builtins::kObjectValues:
503 : case Builtins::kObjectPrototypeHasOwnProperty:
504 : case Builtins::kObjectPrototypeIsPrototypeOf:
505 : case Builtins::kObjectPrototypePropertyIsEnumerable:
506 : case Builtins::kObjectPrototypeToString:
507 : // Array builtins.
508 : case Builtins::kArrayIsArray:
509 : case Builtins::kArrayConstructor:
510 : case Builtins::kArrayIndexOf:
511 : case Builtins::kArrayPrototypeValues:
512 : case Builtins::kArrayIncludes:
513 : case Builtins::kArrayPrototypeEntries:
514 : case Builtins::kArrayPrototypeFill:
515 : case Builtins::kArrayPrototypeFind:
516 : case Builtins::kArrayPrototypeFindIndex:
517 : case Builtins::kArrayPrototypeFlat:
518 : case Builtins::kArrayPrototypeFlatMap:
519 : case Builtins::kArrayPrototypeJoin:
520 : case Builtins::kArrayPrototypeKeys:
521 : case Builtins::kArrayPrototypeLastIndexOf:
522 : case Builtins::kArrayPrototypeSlice:
523 : case Builtins::kArrayPrototypeSort:
524 : case Builtins::kArrayPrototypeToLocaleString:
525 : case Builtins::kArrayPrototypeToString:
526 : case Builtins::kArrayForEach:
527 : case Builtins::kArrayEvery:
528 : case Builtins::kArraySome:
529 : case Builtins::kArrayConcat:
530 : case Builtins::kArrayFilter:
531 : case Builtins::kArrayMap:
532 : case Builtins::kArrayReduce:
533 : case Builtins::kArrayReduceRight:
534 : // Trace builtins.
535 : case Builtins::kIsTraceCategoryEnabled:
536 : case Builtins::kTrace:
537 : // TypedArray builtins.
538 : case Builtins::kTypedArrayConstructor:
539 : case Builtins::kTypedArrayPrototypeBuffer:
540 : case Builtins::kTypedArrayPrototypeByteLength:
541 : case Builtins::kTypedArrayPrototypeByteOffset:
542 : case Builtins::kTypedArrayPrototypeLength:
543 : case Builtins::kTypedArrayPrototypeEntries:
544 : case Builtins::kTypedArrayPrototypeKeys:
545 : case Builtins::kTypedArrayPrototypeValues:
546 : case Builtins::kTypedArrayPrototypeFind:
547 : case Builtins::kTypedArrayPrototypeFindIndex:
548 : case Builtins::kTypedArrayPrototypeIncludes:
549 : case Builtins::kTypedArrayPrototypeIndexOf:
550 : case Builtins::kTypedArrayPrototypeLastIndexOf:
551 : case Builtins::kTypedArrayPrototypeSlice:
552 : case Builtins::kTypedArrayPrototypeSubArray:
553 : case Builtins::kTypedArrayPrototypeEvery:
554 : case Builtins::kTypedArrayPrototypeSome:
555 : case Builtins::kTypedArrayPrototypeFilter:
556 : case Builtins::kTypedArrayPrototypeMap:
557 : case Builtins::kTypedArrayPrototypeReduce:
558 : case Builtins::kTypedArrayPrototypeReduceRight:
559 : case Builtins::kTypedArrayPrototypeForEach:
560 : // ArrayBuffer builtins.
561 : case Builtins::kArrayBufferConstructor:
562 : case Builtins::kArrayBufferPrototypeGetByteLength:
563 : case Builtins::kArrayBufferIsView:
564 : case Builtins::kArrayBufferPrototypeSlice:
565 : case Builtins::kReturnReceiver:
566 : // DataView builtins.
567 : case Builtins::kDataViewConstructor:
568 : case Builtins::kDataViewPrototypeGetBuffer:
569 : case Builtins::kDataViewPrototypeGetByteLength:
570 : case Builtins::kDataViewPrototypeGetByteOffset:
571 : case Builtins::kDataViewPrototypeGetInt8:
572 : case Builtins::kDataViewPrototypeGetUint8:
573 : case Builtins::kDataViewPrototypeGetInt16:
574 : case Builtins::kDataViewPrototypeGetUint16:
575 : case Builtins::kDataViewPrototypeGetInt32:
576 : case Builtins::kDataViewPrototypeGetUint32:
577 : case Builtins::kDataViewPrototypeGetFloat32:
578 : case Builtins::kDataViewPrototypeGetFloat64:
579 : case Builtins::kDataViewPrototypeGetBigInt64:
580 : case Builtins::kDataViewPrototypeGetBigUint64:
581 : // Boolean bulitins.
582 : case Builtins::kBooleanConstructor:
583 : case Builtins::kBooleanPrototypeToString:
584 : case Builtins::kBooleanPrototypeValueOf:
585 : // Date builtins.
586 : case Builtins::kDateConstructor:
587 : case Builtins::kDateNow:
588 : case Builtins::kDateParse:
589 : case Builtins::kDatePrototypeGetDate:
590 : case Builtins::kDatePrototypeGetDay:
591 : case Builtins::kDatePrototypeGetFullYear:
592 : case Builtins::kDatePrototypeGetHours:
593 : case Builtins::kDatePrototypeGetMilliseconds:
594 : case Builtins::kDatePrototypeGetMinutes:
595 : case Builtins::kDatePrototypeGetMonth:
596 : case Builtins::kDatePrototypeGetSeconds:
597 : case Builtins::kDatePrototypeGetTime:
598 : case Builtins::kDatePrototypeGetTimezoneOffset:
599 : case Builtins::kDatePrototypeGetUTCDate:
600 : case Builtins::kDatePrototypeGetUTCDay:
601 : case Builtins::kDatePrototypeGetUTCFullYear:
602 : case Builtins::kDatePrototypeGetUTCHours:
603 : case Builtins::kDatePrototypeGetUTCMilliseconds:
604 : case Builtins::kDatePrototypeGetUTCMinutes:
605 : case Builtins::kDatePrototypeGetUTCMonth:
606 : case Builtins::kDatePrototypeGetUTCSeconds:
607 : case Builtins::kDatePrototypeGetYear:
608 : case Builtins::kDatePrototypeToDateString:
609 : case Builtins::kDatePrototypeToISOString:
610 : case Builtins::kDatePrototypeToUTCString:
611 : case Builtins::kDatePrototypeToString:
612 : case Builtins::kDatePrototypeToTimeString:
613 : case Builtins::kDatePrototypeToJson:
614 : case Builtins::kDatePrototypeToPrimitive:
615 : case Builtins::kDatePrototypeValueOf:
616 : // Map builtins.
617 : case Builtins::kMapConstructor:
618 : case Builtins::kMapPrototypeForEach:
619 : case Builtins::kMapPrototypeGet:
620 : case Builtins::kMapPrototypeHas:
621 : case Builtins::kMapPrototypeEntries:
622 : case Builtins::kMapPrototypeGetSize:
623 : case Builtins::kMapPrototypeKeys:
624 : case Builtins::kMapPrototypeValues:
625 : // WeakMap builtins.
626 : case Builtins::kWeakMapConstructor:
627 : case Builtins::kWeakMapGet:
628 : case Builtins::kWeakMapHas:
629 : // Math builtins.
630 : case Builtins::kMathAbs:
631 : case Builtins::kMathAcos:
632 : case Builtins::kMathAcosh:
633 : case Builtins::kMathAsin:
634 : case Builtins::kMathAsinh:
635 : case Builtins::kMathAtan:
636 : case Builtins::kMathAtanh:
637 : case Builtins::kMathAtan2:
638 : case Builtins::kMathCeil:
639 : case Builtins::kMathCbrt:
640 : case Builtins::kMathExpm1:
641 : case Builtins::kMathClz32:
642 : case Builtins::kMathCos:
643 : case Builtins::kMathCosh:
644 : case Builtins::kMathExp:
645 : case Builtins::kMathFloor:
646 : case Builtins::kMathFround:
647 : case Builtins::kMathHypot:
648 : case Builtins::kMathImul:
649 : case Builtins::kMathLog:
650 : case Builtins::kMathLog1p:
651 : case Builtins::kMathLog2:
652 : case Builtins::kMathLog10:
653 : case Builtins::kMathMax:
654 : case Builtins::kMathMin:
655 : case Builtins::kMathPow:
656 : case Builtins::kMathRandom:
657 : case Builtins::kMathRound:
658 : case Builtins::kMathSign:
659 : case Builtins::kMathSin:
660 : case Builtins::kMathSinh:
661 : case Builtins::kMathSqrt:
662 : case Builtins::kMathTan:
663 : case Builtins::kMathTanh:
664 : case Builtins::kMathTrunc:
665 : // Number builtins.
666 : case Builtins::kNumberConstructor:
667 : case Builtins::kNumberIsFinite:
668 : case Builtins::kNumberIsInteger:
669 : case Builtins::kNumberIsNaN:
670 : case Builtins::kNumberIsSafeInteger:
671 : case Builtins::kNumberParseFloat:
672 : case Builtins::kNumberParseInt:
673 : case Builtins::kNumberPrototypeToExponential:
674 : case Builtins::kNumberPrototypeToFixed:
675 : case Builtins::kNumberPrototypeToPrecision:
676 : case Builtins::kNumberPrototypeToString:
677 : case Builtins::kNumberPrototypeValueOf:
678 : // BigInt builtins.
679 : case Builtins::kBigIntConstructor:
680 : case Builtins::kBigIntAsIntN:
681 : case Builtins::kBigIntAsUintN:
682 : case Builtins::kBigIntPrototypeToString:
683 : case Builtins::kBigIntPrototypeValueOf:
684 : // Set builtins.
685 : case Builtins::kSetConstructor:
686 : case Builtins::kSetPrototypeEntries:
687 : case Builtins::kSetPrototypeForEach:
688 : case Builtins::kSetPrototypeGetSize:
689 : case Builtins::kSetPrototypeHas:
690 : case Builtins::kSetPrototypeValues:
691 : // WeakSet builtins.
692 : case Builtins::kWeakSetConstructor:
693 : case Builtins::kWeakSetHas:
694 : // String builtins. Strings are immutable.
695 : case Builtins::kStringFromCharCode:
696 : case Builtins::kStringFromCodePoint:
697 : case Builtins::kStringConstructor:
698 : case Builtins::kStringPrototypeAnchor:
699 : case Builtins::kStringPrototypeBig:
700 : case Builtins::kStringPrototypeBlink:
701 : case Builtins::kStringPrototypeBold:
702 : case Builtins::kStringPrototypeCharAt:
703 : case Builtins::kStringPrototypeCharCodeAt:
704 : case Builtins::kStringPrototypeCodePointAt:
705 : case Builtins::kStringPrototypeConcat:
706 : case Builtins::kStringPrototypeEndsWith:
707 : case Builtins::kStringPrototypeFixed:
708 : case Builtins::kStringPrototypeFontcolor:
709 : case Builtins::kStringPrototypeFontsize:
710 : case Builtins::kStringPrototypeIncludes:
711 : case Builtins::kStringPrototypeIndexOf:
712 : case Builtins::kStringPrototypeItalics:
713 : case Builtins::kStringPrototypeLastIndexOf:
714 : case Builtins::kStringPrototypeLink:
715 : case Builtins::kStringPrototypeMatchAll:
716 : case Builtins::kStringPrototypePadEnd:
717 : case Builtins::kStringPrototypePadStart:
718 : case Builtins::kStringPrototypeRepeat:
719 : case Builtins::kStringPrototypeSlice:
720 : case Builtins::kStringPrototypeSmall:
721 : case Builtins::kStringPrototypeStartsWith:
722 : case Builtins::kStringPrototypeStrike:
723 : case Builtins::kStringPrototypeSub:
724 : case Builtins::kStringPrototypeSubstr:
725 : case Builtins::kStringPrototypeSubstring:
726 : case Builtins::kStringPrototypeSup:
727 : case Builtins::kStringPrototypeToString:
728 : #ifndef V8_INTL_SUPPORT
729 : case Builtins::kStringPrototypeToLowerCase:
730 : case Builtins::kStringPrototypeToUpperCase:
731 : #endif
732 : case Builtins::kStringPrototypeTrim:
733 : case Builtins::kStringPrototypeTrimEnd:
734 : case Builtins::kStringPrototypeTrimStart:
735 : case Builtins::kStringPrototypeValueOf:
736 : case Builtins::kStringToNumber:
737 : case Builtins::kStringSubstring:
738 : // Symbol builtins.
739 : case Builtins::kSymbolConstructor:
740 : case Builtins::kSymbolKeyFor:
741 : case Builtins::kSymbolPrototypeToString:
742 : case Builtins::kSymbolPrototypeValueOf:
743 : case Builtins::kSymbolPrototypeToPrimitive:
744 : // JSON builtins.
745 : case Builtins::kJsonParse:
746 : case Builtins::kJsonStringify:
747 : // Global function builtins.
748 : case Builtins::kGlobalDecodeURI:
749 : case Builtins::kGlobalDecodeURIComponent:
750 : case Builtins::kGlobalEncodeURI:
751 : case Builtins::kGlobalEncodeURIComponent:
752 : case Builtins::kGlobalEscape:
753 : case Builtins::kGlobalUnescape:
754 : case Builtins::kGlobalIsFinite:
755 : case Builtins::kGlobalIsNaN:
756 : // Function builtins.
757 : case Builtins::kFunctionPrototypeToString:
758 : case Builtins::kFunctionPrototypeBind:
759 : case Builtins::kFastFunctionPrototypeBind:
760 : case Builtins::kFunctionPrototypeCall:
761 : case Builtins::kFunctionPrototypeApply:
762 : // Error builtins.
763 : case Builtins::kErrorConstructor:
764 : case Builtins::kMakeError:
765 : case Builtins::kMakeTypeError:
766 : case Builtins::kMakeSyntaxError:
767 : case Builtins::kMakeRangeError:
768 : case Builtins::kMakeURIError:
769 : // RegExp builtins.
770 : case Builtins::kRegExpConstructor:
771 : // Internal.
772 : case Builtins::kStrictPoisonPillThrower:
773 : case Builtins::kAllocateInNewSpace:
774 : case Builtins::kAllocateInOldSpace:
775 : return DebugInfo::kHasNoSideEffect;
776 :
777 : // Set builtins.
778 : case Builtins::kSetIteratorPrototypeNext:
779 : case Builtins::kSetPrototypeAdd:
780 : case Builtins::kSetPrototypeClear:
781 : case Builtins::kSetPrototypeDelete:
782 : // Array builtins.
783 : case Builtins::kArrayIteratorPrototypeNext:
784 : case Builtins::kArrayPrototypePop:
785 : case Builtins::kArrayPrototypePush:
786 : case Builtins::kArrayPrototypeReverse:
787 : case Builtins::kArrayPrototypeShift:
788 : case Builtins::kArrayPrototypeUnshift:
789 : case Builtins::kArrayPrototypeSplice:
790 : case Builtins::kArrayUnshift:
791 : // Map builtins.
792 : case Builtins::kMapIteratorPrototypeNext:
793 : case Builtins::kMapPrototypeClear:
794 : case Builtins::kMapPrototypeDelete:
795 : case Builtins::kMapPrototypeSet:
796 : // RegExp builtins.
797 : case Builtins::kRegExpPrototypeTest:
798 : case Builtins::kRegExpPrototypeExec:
799 : case Builtins::kRegExpPrototypeSplit:
800 : case Builtins::kRegExpPrototypeFlagsGetter:
801 : case Builtins::kRegExpPrototypeGlobalGetter:
802 : case Builtins::kRegExpPrototypeIgnoreCaseGetter:
803 : case Builtins::kRegExpPrototypeMatchAll:
804 : case Builtins::kRegExpPrototypeMultilineGetter:
805 : case Builtins::kRegExpPrototypeDotAllGetter:
806 : case Builtins::kRegExpPrototypeUnicodeGetter:
807 : case Builtins::kRegExpPrototypeStickyGetter:
808 427 : return DebugInfo::kRequiresRuntimeChecks;
809 : default:
810 2031 : if (FLAG_trace_side_effect_free_debug_evaluate) {
811 : PrintF("[debug-evaluate] built-in %s may cause side effect.\n",
812 0 : Builtins::name(id));
813 : }
814 : return DebugInfo::kHasSideEffects;
815 : }
816 : }
817 :
818 : bool BytecodeRequiresRuntimeCheck(interpreter::Bytecode bytecode) {
819 : typedef interpreter::Bytecode Bytecode;
820 : switch (bytecode) {
821 : case Bytecode::kStaNamedProperty:
822 : case Bytecode::kStaNamedPropertyNoFeedback:
823 : case Bytecode::kStaNamedOwnProperty:
824 : case Bytecode::kStaKeyedProperty:
825 : case Bytecode::kStaInArrayLiteral:
826 : case Bytecode::kStaDataPropertyInLiteral:
827 : case Bytecode::kStaCurrentContextSlot:
828 : return true;
829 : default:
830 : return false;
831 : }
832 : }
833 :
834 : } // anonymous namespace
835 :
836 : // static
837 12158 : DebugInfo::SideEffectState DebugEvaluate::FunctionGetSideEffectState(
838 : Isolate* isolate, Handle<SharedFunctionInfo> info) {
839 12158 : if (FLAG_trace_side_effect_free_debug_evaluate) {
840 : PrintF("[debug-evaluate] Checking function %s for side effect.\n",
841 0 : info->DebugName()->ToCString().get());
842 : }
843 :
844 : DCHECK(info->is_compiled());
845 12158 : if (info->HasBytecodeArray()) {
846 : // Check bytecodes against whitelist.
847 11456 : Handle<BytecodeArray> bytecode_array(info->GetBytecodeArray(), isolate);
848 5728 : if (FLAG_trace_side_effect_free_debug_evaluate) {
849 0 : bytecode_array->Print();
850 : }
851 : bool requires_runtime_checks = false;
852 84755 : for (interpreter::BytecodeArrayIterator it(bytecode_array); !it.done();
853 73299 : it.Advance()) {
854 73452 : interpreter::Bytecode bytecode = it.current_bytecode();
855 :
856 73452 : if (interpreter::Bytecodes::IsCallRuntime(bytecode)) {
857 : Runtime::FunctionId id =
858 : (bytecode == interpreter::Bytecode::kInvokeIntrinsic)
859 : ? it.GetIntrinsicIdOperand(0)
860 1319 : : it.GetRuntimeIdOperand(0);
861 1319 : if (IntrinsicHasNoSideEffect(id)) continue;
862 153 : return DebugInfo::kHasSideEffects;
863 : }
864 :
865 72133 : if (BytecodeHasNoSideEffect(bytecode)) continue;
866 2446 : if (BytecodeRequiresRuntimeCheck(bytecode)) {
867 : requires_runtime_checks = true;
868 : continue;
869 : }
870 :
871 90 : if (FLAG_trace_side_effect_free_debug_evaluate) {
872 : PrintF("[debug-evaluate] bytecode %s may cause side effect.\n",
873 0 : interpreter::Bytecodes::ToString(bytecode));
874 : }
875 :
876 : // Did not match whitelist.
877 : return DebugInfo::kHasSideEffects;
878 : }
879 : return requires_runtime_checks ? DebugInfo::kRequiresRuntimeChecks
880 11150 : : DebugInfo::kHasNoSideEffect;
881 6430 : } else if (info->IsApiFunction()) {
882 316 : if (info->GetCode()->is_builtin()) {
883 316 : return info->GetCode()->builtin_index() == Builtins::kHandleApiCall
884 : ? DebugInfo::kHasNoSideEffect
885 158 : : DebugInfo::kHasSideEffects;
886 : }
887 : } else {
888 : // Check built-ins against whitelist.
889 : int builtin_index =
890 12544 : info->HasBuiltinId() ? info->builtin_id() : Builtins::kNoBuiltinId;
891 6272 : if (!Builtins::IsBuiltinId(builtin_index))
892 : return DebugInfo::kHasSideEffects;
893 : DebugInfo::SideEffectState state =
894 6272 : BuiltinGetSideEffectState(static_cast<Builtins::Name>(builtin_index));
895 6272 : return state;
896 : }
897 :
898 : return DebugInfo::kHasSideEffects;
899 : }
900 :
901 : #ifdef DEBUG
902 : static bool TransitivelyCalledBuiltinHasNoSideEffect(Builtins::Name caller,
903 : Builtins::Name callee) {
904 : switch (callee) {
905 : // Transitively called Builtins:
906 : case Builtins::kAbort:
907 : case Builtins::kAbortJS:
908 : case Builtins::kAdaptorWithBuiltinExitFrame:
909 : case Builtins::kArrayConstructorImpl:
910 : case Builtins::kArrayEveryLoopContinuation:
911 : case Builtins::kArrayFilterLoopContinuation:
912 : case Builtins::kArrayFindIndexLoopContinuation:
913 : case Builtins::kArrayFindLoopContinuation:
914 : case Builtins::kArrayForEachLoopContinuation:
915 : case Builtins::kArrayIncludesHoleyDoubles:
916 : case Builtins::kArrayIncludesPackedDoubles:
917 : case Builtins::kArrayIncludesSmiOrObject:
918 : case Builtins::kArrayIndexOfHoleyDoubles:
919 : case Builtins::kArrayIndexOfPackedDoubles:
920 : case Builtins::kArrayIndexOfSmiOrObject:
921 : case Builtins::kArrayMapLoopContinuation:
922 : case Builtins::kArrayReduceLoopContinuation:
923 : case Builtins::kArrayReduceRightLoopContinuation:
924 : case Builtins::kArraySomeLoopContinuation:
925 : case Builtins::kArrayTimSort:
926 : case Builtins::kCall_ReceiverIsAny:
927 : case Builtins::kCallWithArrayLike:
928 : case Builtins::kCEntry_Return1_DontSaveFPRegs_ArgvOnStack_NoBuiltinExit:
929 : case Builtins::kCEntry_Return1_DontSaveFPRegs_ArgvOnStack_BuiltinExit:
930 : case Builtins::kCEntry_Return1_DontSaveFPRegs_ArgvInRegister_NoBuiltinExit:
931 : case Builtins::kCEntry_Return1_SaveFPRegs_ArgvOnStack_NoBuiltinExit:
932 : case Builtins::kCEntry_Return1_SaveFPRegs_ArgvOnStack_BuiltinExit:
933 : case Builtins::kCEntry_Return2_DontSaveFPRegs_ArgvOnStack_NoBuiltinExit:
934 : case Builtins::kCEntry_Return2_DontSaveFPRegs_ArgvOnStack_BuiltinExit:
935 : case Builtins::kCEntry_Return2_DontSaveFPRegs_ArgvInRegister_NoBuiltinExit:
936 : case Builtins::kCEntry_Return2_SaveFPRegs_ArgvOnStack_NoBuiltinExit:
937 : case Builtins::kCEntry_Return2_SaveFPRegs_ArgvOnStack_BuiltinExit:
938 : case Builtins::kCloneFastJSArray:
939 : case Builtins::kConstruct:
940 : case Builtins::kConvertToLocaleString:
941 : case Builtins::kCreateTypedArray:
942 : case Builtins::kDirectCEntry:
943 : case Builtins::kDoubleToI:
944 : case Builtins::kExtractFastJSArray:
945 : case Builtins::kFastNewObject:
946 : case Builtins::kFindOrderedHashMapEntry:
947 : case Builtins::kFlatMapIntoArray:
948 : case Builtins::kFlattenIntoArray:
949 : case Builtins::kGetProperty:
950 : case Builtins::kHasProperty:
951 : case Builtins::kNonNumberToNumber:
952 : case Builtins::kNonPrimitiveToPrimitive_Number:
953 : case Builtins::kNumberToString:
954 : case Builtins::kObjectToString:
955 : case Builtins::kOrderedHashTableHealIndex:
956 : case Builtins::kOrdinaryToPrimitive_Number:
957 : case Builtins::kOrdinaryToPrimitive_String:
958 : case Builtins::kParseInt:
959 : case Builtins::kProxyHasProperty:
960 : case Builtins::kRecordWrite:
961 : case Builtins::kStringAdd_CheckNone:
962 : case Builtins::kStringEqual:
963 : case Builtins::kStringIndexOf:
964 : case Builtins::kStringRepeat:
965 : case Builtins::kToInteger:
966 : case Builtins::kToInteger_TruncateMinusZero:
967 : case Builtins::kToLength:
968 : case Builtins::kToName:
969 : case Builtins::kToObject:
970 : case Builtins::kToString:
971 : case Builtins::kWeakMapLookupHashIndex:
972 : return true;
973 : case Builtins::kJoinStackPop:
974 : case Builtins::kJoinStackPush:
975 : switch (caller) {
976 : case Builtins::kArrayPrototypeJoin:
977 : case Builtins::kArrayPrototypeToLocaleString:
978 : return true;
979 : default:
980 : return false;
981 : }
982 : case Builtins::kSetProperty:
983 : switch (caller) {
984 : case Builtins::kArrayPrototypeSlice:
985 : case Builtins::kTypedArrayPrototypeMap:
986 : case Builtins::kStringPrototypeMatchAll:
987 : return true;
988 : default:
989 : return false;
990 : }
991 : default:
992 : return false;
993 : }
994 : }
995 :
996 : // static
997 : void DebugEvaluate::VerifyTransitiveBuiltins(Isolate* isolate) {
998 : // TODO(yangguo): also check runtime calls.
999 : bool failed = false;
1000 : bool sanity_check = false;
1001 : for (int i = 0; i < Builtins::builtin_count; i++) {
1002 : Builtins::Name caller = static_cast<Builtins::Name>(i);
1003 : DebugInfo::SideEffectState state = BuiltinGetSideEffectState(caller);
1004 : if (state != DebugInfo::kHasNoSideEffect) continue;
1005 : Code code = isolate->builtins()->builtin(caller);
1006 : int mode = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
1007 : RelocInfo::ModeMask(RelocInfo::RELATIVE_CODE_TARGET);
1008 :
1009 : for (RelocIterator it(code, mode); !it.done(); it.next()) {
1010 : RelocInfo* rinfo = it.rinfo();
1011 : DCHECK(RelocInfo::IsCodeTargetMode(rinfo->rmode()));
1012 : Code callee_code = isolate->heap()->GcSafeFindCodeForInnerPointer(
1013 : rinfo->target_address());
1014 : if (!callee_code->is_builtin()) continue;
1015 : Builtins::Name callee =
1016 : static_cast<Builtins::Name>(callee_code->builtin_index());
1017 : if (BuiltinGetSideEffectState(callee) == DebugInfo::kHasNoSideEffect) {
1018 : continue;
1019 : }
1020 : if (TransitivelyCalledBuiltinHasNoSideEffect(caller, callee)) {
1021 : sanity_check = true;
1022 : continue;
1023 : }
1024 : PrintF("Whitelisted builtin %s calls non-whitelisted builtin %s\n",
1025 : Builtins::name(caller), Builtins::name(callee));
1026 : failed = true;
1027 : }
1028 : }
1029 : CHECK(!failed);
1030 : #if defined(V8_TARGET_ARCH_PPC) || defined(V8_TARGET_ARCH_MIPS64)
1031 : // Isolate-independent builtin calls and jumps do not emit reloc infos
1032 : // on PPC. We try to avoid using PC relative code due to performance
1033 : // issue with especially older hardwares.
1034 : // MIPS64 doesn't have PC relative code currently.
1035 : // TODO(mips): Add PC relative code to MIPS64.
1036 : USE(sanity_check);
1037 : #else
1038 : CHECK(sanity_check);
1039 : #endif
1040 : }
1041 : #endif // DEBUG
1042 :
1043 : // static
1044 6689 : void DebugEvaluate::ApplySideEffectChecks(
1045 : Handle<BytecodeArray> bytecode_array) {
1046 137280 : for (interpreter::BytecodeArrayIterator it(bytecode_array); !it.done();
1047 123902 : it.Advance()) {
1048 123902 : interpreter::Bytecode bytecode = it.current_bytecode();
1049 123902 : if (BytecodeRequiresRuntimeCheck(bytecode)) it.ApplyDebugBreak();
1050 : }
1051 6689 : }
1052 :
1053 : } // namespace internal
1054 178779 : } // namespace v8
|