Index: src/debug/debug-evaluate.cc |
diff --git a/src/debug/debug-evaluate.cc b/src/debug/debug-evaluate.cc |
index 8ac0a4c11d1b02a0def650e565efabce602c4444..b6ed28e39fa22dd6d894fa5eda9eb1195ab0d268 100644 |
--- a/src/debug/debug-evaluate.cc |
+++ b/src/debug/debug-evaluate.cc |
@@ -260,58 +260,80 @@ namespace { |
bool IntrinsicHasNoSideEffect(Runtime::FunctionId id) { |
// Use macro to include both inlined and non-inlined version of an intrinsic. |
-#define INTRINSIC_WHITELIST(V) \ |
- /* Conversions */ \ |
- V(ToInteger) \ |
- V(ToObject) \ |
- V(ToString) \ |
- V(ToLength) \ |
- V(ToNumber) \ |
- /* Type checks */ \ |
- V(IsJSReceiver) \ |
- V(IsSmi) \ |
- V(IsArray) \ |
- V(IsFunction) \ |
- V(IsDate) \ |
- V(IsJSProxy) \ |
- V(IsRegExp) \ |
- V(IsTypedArray) \ |
- V(ClassOf) \ |
- /* Loads */ \ |
- V(LoadLookupSlotForCall) \ |
- /* Arrays */ \ |
- V(ArraySpeciesConstructor) \ |
- V(NormalizeElements) \ |
- V(GetArrayKeys) \ |
- V(HasComplexElements) \ |
- V(EstimateNumberOfElements) \ |
- /* Errors */ \ |
- V(ReThrow) \ |
- V(ThrowReferenceError) \ |
- V(ThrowSymbolIteratorInvalid) \ |
- V(ThrowIteratorResultNotAnObject) \ |
- V(NewTypeError) \ |
- /* Strings */ \ |
- V(StringCharCodeAt) \ |
- V(StringIndexOf) \ |
- V(StringReplaceOneCharWithString) \ |
- V(SubString) \ |
- V(RegExpInternalReplace) \ |
- /* Literals */ \ |
- V(CreateArrayLiteral) \ |
- V(CreateObjectLiteral) \ |
- V(CreateRegExpLiteral) \ |
- /* Collections */ \ |
- V(JSCollectionGetTable) \ |
- V(FixedArrayGet) \ |
- V(StringGetRawHashField) \ |
- V(GenericHash) \ |
- V(MapIteratorInitialize) \ |
- V(MapInitialize) \ |
- /* Misc. */ \ |
- V(ForInPrepare) \ |
- V(Call) \ |
- V(MaxSmi) \ |
+#define INTRINSIC_WHITELIST(V) \ |
+ /* Conversions */ \ |
+ V(ToInteger) \ |
+ V(ToObject) \ |
+ V(ToString) \ |
+ V(ToLength) \ |
+ V(ToNumber) \ |
+ /* Type checks */ \ |
+ V(IsJSReceiver) \ |
+ V(IsSmi) \ |
+ V(IsArray) \ |
+ V(IsFunction) \ |
+ V(IsDate) \ |
+ V(IsJSProxy) \ |
+ V(IsRegExp) \ |
+ V(IsTypedArray) \ |
+ V(ClassOf) \ |
+ /* Loads */ \ |
+ V(LoadLookupSlotForCall) \ |
+ /* Arrays */ \ |
+ V(ArraySpeciesConstructor) \ |
+ V(NormalizeElements) \ |
+ V(GetArrayKeys) \ |
+ V(HasComplexElements) \ |
+ V(EstimateNumberOfElements) \ |
+ /* Errors */ \ |
+ V(ReThrow) \ |
+ V(ThrowReferenceError) \ |
+ V(ThrowSymbolIteratorInvalid) \ |
+ V(ThrowIteratorResultNotAnObject) \ |
+ V(NewTypeError) \ |
+ /* Strings */ \ |
+ V(StringCharCodeAt) \ |
+ V(StringIndexOf) \ |
+ V(StringReplaceOneCharWithString) \ |
+ V(SubString) \ |
+ V(RegExpInternalReplace) \ |
+ /* Literals */ \ |
+ V(CreateArrayLiteral) \ |
+ V(CreateObjectLiteral) \ |
+ V(CreateRegExpLiteral) \ |
+ /* Collections */ \ |
+ V(JSCollectionGetTable) \ |
+ V(FixedArrayGet) \ |
+ V(StringGetRawHashField) \ |
+ V(GenericHash) \ |
+ V(MapIteratorInitialize) \ |
+ V(MapInitialize) \ |
+ /* Called from builtins */ \ |
+ V(StringParseFloat) \ |
+ V(StringParseInt) \ |
+ V(StringCharCodeAtRT) \ |
+ V(StringIndexOfUnchecked) \ |
+ V(SymbolDescriptiveString) \ |
+ V(GenerateRandomNumbers) \ |
+ V(ExternalStringGetChar) \ |
+ V(GlobalPrint) \ |
+ V(AllocateInNewSpace) \ |
+ V(AllocateSeqOneByteString) \ |
+ V(AllocateSeqTwoByteString) \ |
+ V(ObjectCreate) \ |
+ V(ObjectHasOwnProperty) \ |
+ V(ArrayIndexOf) \ |
+ V(ArrayIncludes_Slow) \ |
+ V(ArrayIsArray) \ |
+ V(ThrowTypeError) \ |
+ V(ThrowCalledOnNullOrUndefined) \ |
+ V(ThrowIncompatibleMethodReceiver) \ |
+ V(ThrowInvalidHint) \ |
+ V(ThrowNotDateError) \ |
+ /* Misc. */ \ |
+ V(ForInPrepare) \ |
+ V(Call) \ |
+ V(MaxSmi) \ |
V(HasInPrototypeChain) |
#define CASE(Name) \ |
@@ -649,6 +671,22 @@ bool DebugEvaluate::FunctionHasNoSideEffect(Handle<SharedFunctionInfo> info) { |
int builtin_index = info->code()->builtin_index(); |
if (builtin_index >= 0 && builtin_index < Builtins::builtin_count && |
BuiltinHasNoSideEffect(static_cast<Builtins::Name>(builtin_index))) { |
+#ifdef DEBUG |
+ int mode = RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE); |
+ bool failed = false; |
+ for (RelocIterator it(info->code(), mode); !it.done(); it.next()) { |
+ RelocInfo* rinfo = it.rinfo(); |
+ Address address = rinfo->target_external_reference(); |
+ const Runtime::Function* function = Runtime::FunctionForEntry(address); |
+ if (function == nullptr) continue; |
+ if (!IntrinsicHasNoSideEffect(function->function_id)) { |
+ PrintF("Whitelisted builtin %s calls non-whitelisted intrinsic %s\n", |
+ Builtins::name(builtin_index), function->name); |
+ failed = true; |
+ } |
+ CHECK(!failed); |
+ } |
+#endif // DEBUG |
return true; |
} |
} |