OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/debug/debug-evaluate.h" | 5 #include "src/debug/debug-evaluate.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/compiler.h" | 8 #include "src/compiler.h" |
9 #include "src/contexts.h" | 9 #include "src/contexts.h" |
10 #include "src/debug/debug-frames.h" | 10 #include "src/debug/debug-frames.h" |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 !frame_->receiver()->IsTheHole(isolate_)) { | 253 !frame_->receiver()->IsTheHole(isolate_)) { |
254 recv = handle(frame_->receiver(), isolate_); | 254 recv = handle(frame_->receiver(), isolate_); |
255 } | 255 } |
256 JSObject::SetOwnPropertyIgnoreAttributes(target, name, recv, NONE).Check(); | 256 JSObject::SetOwnPropertyIgnoreAttributes(target, name, recv, NONE).Check(); |
257 } | 257 } |
258 | 258 |
259 namespace { | 259 namespace { |
260 | 260 |
261 bool IntrinsicHasNoSideEffect(Runtime::FunctionId id) { | 261 bool IntrinsicHasNoSideEffect(Runtime::FunctionId id) { |
262 // Use macro to include both inlined and non-inlined version of an intrinsic. | 262 // Use macro to include both inlined and non-inlined version of an intrinsic. |
263 #define INTRINSIC_WHITELIST(V) \ | 263 #define INTRINSIC_WHITELIST(V) \ |
264 /* Conversions */ \ | 264 /* Conversions */ \ |
265 V(ToInteger) \ | 265 V(ToInteger) \ |
266 V(ToObject) \ | 266 V(ToObject) \ |
267 V(ToString) \ | 267 V(ToString) \ |
268 V(ToLength) \ | 268 V(ToLength) \ |
269 V(ToNumber) \ | 269 V(ToNumber) \ |
270 /* Type checks */ \ | 270 /* Type checks */ \ |
271 V(IsJSReceiver) \ | 271 V(IsJSReceiver) \ |
272 V(IsSmi) \ | 272 V(IsSmi) \ |
273 V(IsArray) \ | 273 V(IsArray) \ |
274 V(IsFunction) \ | 274 V(IsFunction) \ |
275 V(IsDate) \ | 275 V(IsDate) \ |
276 V(IsJSProxy) \ | 276 V(IsJSProxy) \ |
277 V(IsRegExp) \ | 277 V(IsRegExp) \ |
278 V(IsTypedArray) \ | 278 V(IsTypedArray) \ |
279 V(ClassOf) \ | 279 V(ClassOf) \ |
280 /* Loads */ \ | 280 /* Loads */ \ |
281 V(LoadLookupSlotForCall) \ | 281 V(LoadLookupSlotForCall) \ |
282 /* Arrays */ \ | 282 /* Arrays */ \ |
283 V(ArraySpeciesConstructor) \ | 283 V(ArraySpeciesConstructor) \ |
284 V(NormalizeElements) \ | 284 V(NormalizeElements) \ |
285 V(GetArrayKeys) \ | 285 V(GetArrayKeys) \ |
286 V(HasComplexElements) \ | 286 V(HasComplexElements) \ |
287 V(EstimateNumberOfElements) \ | 287 V(EstimateNumberOfElements) \ |
288 /* Errors */ \ | 288 /* Errors */ \ |
289 V(ReThrow) \ | 289 V(ReThrow) \ |
290 V(ThrowReferenceError) \ | 290 V(ThrowReferenceError) \ |
291 V(ThrowSymbolIteratorInvalid) \ | 291 V(ThrowSymbolIteratorInvalid) \ |
292 V(ThrowIteratorResultNotAnObject) \ | 292 V(ThrowIteratorResultNotAnObject) \ |
293 V(NewTypeError) \ | 293 V(NewTypeError) \ |
294 /* Strings */ \ | 294 /* Strings */ \ |
295 V(StringCharCodeAt) \ | 295 V(StringCharCodeAt) \ |
296 V(StringIndexOf) \ | 296 V(StringIndexOf) \ |
297 V(StringReplaceOneCharWithString) \ | 297 V(StringReplaceOneCharWithString) \ |
298 V(SubString) \ | 298 V(SubString) \ |
299 V(RegExpInternalReplace) \ | 299 V(RegExpInternalReplace) \ |
300 /* Literals */ \ | 300 /* Literals */ \ |
301 V(CreateArrayLiteral) \ | 301 V(CreateArrayLiteral) \ |
302 V(CreateObjectLiteral) \ | 302 V(CreateObjectLiteral) \ |
303 V(CreateRegExpLiteral) \ | 303 V(CreateRegExpLiteral) \ |
304 /* Collections */ \ | 304 /* Collections */ \ |
305 V(JSCollectionGetTable) \ | 305 V(JSCollectionGetTable) \ |
306 V(FixedArrayGet) \ | 306 V(FixedArrayGet) \ |
307 V(StringGetRawHashField) \ | 307 V(StringGetRawHashField) \ |
308 V(GenericHash) \ | 308 V(GenericHash) \ |
309 V(MapIteratorInitialize) \ | 309 V(MapIteratorInitialize) \ |
310 V(MapInitialize) \ | 310 V(MapInitialize) \ |
311 /* Misc. */ \ | 311 /* Called from builtins */ \ |
312 V(ForInPrepare) \ | 312 V(StringParseFloat) \ |
313 V(Call) \ | 313 V(StringParseInt) \ |
314 V(MaxSmi) \ | 314 V(StringCharCodeAtRT) \ |
| 315 V(StringIndexOfUnchecked) \ |
| 316 V(SymbolDescriptiveString) \ |
| 317 V(GenerateRandomNumbers) \ |
| 318 V(ExternalStringGetChar) \ |
| 319 V(GlobalPrint) \ |
| 320 V(AllocateInNewSpace) \ |
| 321 V(AllocateSeqOneByteString) \ |
| 322 V(AllocateSeqTwoByteString) \ |
| 323 V(ObjectCreate) \ |
| 324 V(ObjectHasOwnProperty) \ |
| 325 V(ArrayIndexOf) \ |
| 326 V(ArrayIncludes_Slow) \ |
| 327 V(ArrayIsArray) \ |
| 328 V(ThrowTypeError) \ |
| 329 V(ThrowCalledOnNullOrUndefined) \ |
| 330 V(ThrowIncompatibleMethodReceiver) \ |
| 331 V(ThrowInvalidHint) \ |
| 332 V(ThrowNotDateError) \ |
| 333 /* Misc. */ \ |
| 334 V(ForInPrepare) \ |
| 335 V(Call) \ |
| 336 V(MaxSmi) \ |
315 V(HasInPrototypeChain) | 337 V(HasInPrototypeChain) |
316 | 338 |
317 #define CASE(Name) \ | 339 #define CASE(Name) \ |
318 case Runtime::k##Name: \ | 340 case Runtime::k##Name: \ |
319 case Runtime::kInline##Name: | 341 case Runtime::kInline##Name: |
320 | 342 |
321 switch (id) { | 343 switch (id) { |
322 INTRINSIC_WHITELIST(CASE) | 344 INTRINSIC_WHITELIST(CASE) |
323 return true; | 345 return true; |
324 default: | 346 default: |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
642 | 664 |
643 // Did not match whitelist. | 665 // Did not match whitelist. |
644 return false; | 666 return false; |
645 } | 667 } |
646 return true; | 668 return true; |
647 } else { | 669 } else { |
648 // Check built-ins against whitelist. | 670 // Check built-ins against whitelist. |
649 int builtin_index = info->code()->builtin_index(); | 671 int builtin_index = info->code()->builtin_index(); |
650 if (builtin_index >= 0 && builtin_index < Builtins::builtin_count && | 672 if (builtin_index >= 0 && builtin_index < Builtins::builtin_count && |
651 BuiltinHasNoSideEffect(static_cast<Builtins::Name>(builtin_index))) { | 673 BuiltinHasNoSideEffect(static_cast<Builtins::Name>(builtin_index))) { |
| 674 #ifdef DEBUG |
| 675 int mode = RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE); |
| 676 bool failed = false; |
| 677 for (RelocIterator it(info->code(), mode); !it.done(); it.next()) { |
| 678 RelocInfo* rinfo = it.rinfo(); |
| 679 Address address = rinfo->target_external_reference(); |
| 680 const Runtime::Function* function = Runtime::FunctionForEntry(address); |
| 681 if (function == nullptr) continue; |
| 682 if (!IntrinsicHasNoSideEffect(function->function_id)) { |
| 683 PrintF("Whitelisted builtin %s calls non-whitelisted intrinsic %s\n", |
| 684 Builtins::name(builtin_index), function->name); |
| 685 failed = true; |
| 686 } |
| 687 CHECK(!failed); |
| 688 } |
| 689 #endif // DEBUG |
652 return true; | 690 return true; |
653 } | 691 } |
654 } | 692 } |
655 | 693 |
656 return false; | 694 return false; |
657 } | 695 } |
658 | 696 |
659 // static | 697 // static |
660 bool DebugEvaluate::CallbackHasNoSideEffect(Address function_addr) { | 698 bool DebugEvaluate::CallbackHasNoSideEffect(Address function_addr) { |
661 for (size_t i = 0; i < arraysize(accessors_with_no_side_effect); i++) { | 699 for (size_t i = 0; i < arraysize(accessors_with_no_side_effect); i++) { |
662 if (function_addr == accessors_with_no_side_effect[i]) return true; | 700 if (function_addr == accessors_with_no_side_effect[i]) return true; |
663 } | 701 } |
664 | 702 |
665 if (FLAG_trace_side_effect_free_debug_evaluate) { | 703 if (FLAG_trace_side_effect_free_debug_evaluate) { |
666 PrintF("[debug-evaluate] API Callback at %p may cause side effect.\n", | 704 PrintF("[debug-evaluate] API Callback at %p may cause side effect.\n", |
667 reinterpret_cast<void*>(function_addr)); | 705 reinterpret_cast<void*>(function_addr)); |
668 } | 706 } |
669 return false; | 707 return false; |
670 } | 708 } |
671 | 709 |
672 } // namespace internal | 710 } // namespace internal |
673 } // namespace v8 | 711 } // namespace v8 |
OLD | NEW |