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

Side by Side Diff: src/runtime.cc

Issue 11971015: Skip stack trace formatting in case the global object is already dead. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: fix leaks in the setter. Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/runtime.h ('k') | test/cctest/cctest.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 4137 matching lines...) Expand 10 before | Expand all | Expand 10 after
4148 obj_value, 4148 obj_value,
4149 attr); 4149 attr);
4150 } 4150 }
4151 4151
4152 4152
4153 // Return property without being observable by accessors or interceptors. 4153 // Return property without being observable by accessors or interceptors.
4154 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDataProperty) { 4154 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDataProperty) {
4155 ASSERT(args.length() == 2); 4155 ASSERT(args.length() == 2);
4156 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); 4156 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
4157 CONVERT_ARG_HANDLE_CHECKED(String, key, 1); 4157 CONVERT_ARG_HANDLE_CHECKED(String, key, 1);
4158 // In rare cases the global object backing the global proxy may already be
4159 // invalid. In that case, return undefined.
4160 if (object->IsJSGlobalProxy() &&
4161 !object->GetPrototype()->IsJSGlobalObject()) {
4162 return isolate->heap()->undefined_value();
4163 }
4158 LookupResult lookup(isolate); 4164 LookupResult lookup(isolate);
4159 object->LookupRealNamedProperty(*key, &lookup); 4165 object->LookupRealNamedProperty(*key, &lookup);
4160 if (!lookup.IsFound()) return isolate->heap()->undefined_value(); 4166 if (!lookup.IsFound()) return isolate->heap()->undefined_value();
4161 switch (lookup.type()) { 4167 switch (lookup.type()) {
4162 case NORMAL: 4168 case NORMAL:
4163 return lookup.holder()->GetNormalizedProperty(&lookup); 4169 return lookup.holder()->GetNormalizedProperty(&lookup);
4164 case FIELD: 4170 case FIELD:
4165 return lookup.holder()->FastPropertyAt( 4171 return lookup.holder()->FastPropertyAt(
4166 lookup.GetFieldIndex().field_index()); 4172 lookup.GetFieldIndex().field_index());
4167 case CONSTANT_FUNCTION: 4173 case CONSTANT_FUNCTION:
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after
4637 ASSERT(args.length() == 2); 4643 ASSERT(args.length() == 2);
4638 4644
4639 CONVERT_ARG_CHECKED(JSObject, object, 0); 4645 CONVERT_ARG_CHECKED(JSObject, object, 0);
4640 CONVERT_ARG_CHECKED(String, key, 1); 4646 CONVERT_ARG_CHECKED(String, key, 1);
4641 4647
4642 PropertyAttributes att = object->GetLocalPropertyAttribute(key); 4648 PropertyAttributes att = object->GetLocalPropertyAttribute(key);
4643 return isolate->heap()->ToBoolean(att != ABSENT && (att & DONT_ENUM) == 0); 4649 return isolate->heap()->ToBoolean(att != ABSENT && (att & DONT_ENUM) == 0);
4644 } 4650 }
4645 4651
4646 4652
4647 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNames) { 4653 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNamesNoSideEffect) {
4648 HandleScope scope(isolate); 4654 HandleScope scope(isolate);
4649 ASSERT(args.length() == 1); 4655 ASSERT(args.length() == 1);
4650 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); 4656 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
4657 // In rare cases the global object backing the global proxy may already be
4658 // invalid. In that case, return an empty array.
4659 if (object->IsJSGlobalProxy() &&
4660 !object->GetPrototype()->IsJSGlobalObject()) {
4661 return *isolate->factory()->NewJSArray(0);
4662 }
4651 bool threw = false; 4663 bool threw = false;
4652 Handle<JSArray> result = GetKeysFor(object, &threw); 4664 Handle<FixedArray> elements =
4665 GetKeysInFixedArrayFor<false>(object, INCLUDE_PROTOS, &threw);
4653 if (threw) return Failure::Exception(); 4666 if (threw) return Failure::Exception();
4654 return *result; 4667 return *isolate->factory()->NewJSArrayWithElements(elements);
4655 } 4668 }
4656 4669
4657 4670
4658 // Returns either a FixedArray as Runtime_GetPropertyNames, 4671 // Returns either a FixedArray as Runtime_GetPropertyNames,
4659 // or, if the given object has an enum cache that contains 4672 // or, if the given object has an enum cache that contains
4660 // all enumerable properties of the object and its prototypes 4673 // all enumerable properties of the object and its prototypes
4661 // have none, the map of the object. This is used to speed up 4674 // have none, the map of the object. This is used to speed up
4662 // the check for deletions during a for-in. 4675 // the check for deletions during a for-in.
4663 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNamesFast) { 4676 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNamesFast) {
4664 ASSERT(args.length() == 1); 4677 ASSERT(args.length() == 1);
4665 4678
4666 CONVERT_ARG_CHECKED(JSReceiver, raw_object, 0); 4679 CONVERT_ARG_CHECKED(JSReceiver, raw_object, 0);
4667 4680
4668 if (raw_object->IsSimpleEnum()) return raw_object->map(); 4681 if (raw_object->IsSimpleEnum()) return raw_object->map();
4669 4682
4670 HandleScope scope(isolate); 4683 HandleScope scope(isolate);
4671 Handle<JSReceiver> object(raw_object); 4684 Handle<JSReceiver> object(raw_object);
4672 bool threw = false; 4685 bool threw = false;
4673 Handle<FixedArray> content = 4686 Handle<FixedArray> content =
4674 GetKeysInFixedArrayFor(object, INCLUDE_PROTOS, &threw); 4687 GetKeysInFixedArrayFor<true>(object, INCLUDE_PROTOS, &threw);
4675 if (threw) return Failure::Exception(); 4688 if (threw) return Failure::Exception();
4676 4689
4677 // Test again, since cache may have been built by preceding call. 4690 // Test again, since cache may have been built by preceding call.
4678 if (object->IsSimpleEnum()) return object->map(); 4691 if (object->IsSimpleEnum()) return object->map();
4679 4692
4680 return *content; 4693 return *content;
4681 } 4694 }
4682 4695
4683 4696
4684 // Find the length of the prototype chain that is to to handled as one. If a 4697 // Find the length of the prototype chain that is to to handled as one. If a
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
4864 } 4877 }
4865 4878
4866 Handle<Object> proto(object->GetPrototype()); 4879 Handle<Object> proto(object->GetPrototype());
4867 // If proxy is detached we simply return an empty array. 4880 // If proxy is detached we simply return an empty array.
4868 if (proto->IsNull()) return *isolate->factory()->NewJSArray(0); 4881 if (proto->IsNull()) return *isolate->factory()->NewJSArray(0);
4869 object = Handle<JSObject>::cast(proto); 4882 object = Handle<JSObject>::cast(proto);
4870 } 4883 }
4871 4884
4872 bool threw = false; 4885 bool threw = false;
4873 Handle<FixedArray> contents = 4886 Handle<FixedArray> contents =
4874 GetKeysInFixedArrayFor(object, LOCAL_ONLY, &threw); 4887 GetKeysInFixedArrayFor<true>(object, LOCAL_ONLY, &threw);
4875 if (threw) return Failure::Exception(); 4888 if (threw) return Failure::Exception();
4876 4889
4877 // Some fast paths through GetKeysInFixedArrayFor reuse a cached 4890 // Some fast paths through GetKeysInFixedArrayFor reuse a cached
4878 // property array and since the result is mutable we have to create 4891 // property array and since the result is mutable we have to create
4879 // a fresh clone on each invocation. 4892 // a fresh clone on each invocation.
4880 int length = contents->length(); 4893 int length = contents->length();
4881 Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length); 4894 Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length);
4882 for (int i = 0; i < length; i++) { 4895 for (int i = 0; i < length; i++) {
4883 Object* entry = contents->get(i); 4896 Object* entry = contents->get(i);
4884 if (entry->IsString()) { 4897 if (entry->IsString()) {
(...skipping 5129 matching lines...) Expand 10 before | Expand all | Expand 10 after
10014 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArrayKeys) { 10027 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArrayKeys) {
10015 ASSERT(args.length() == 2); 10028 ASSERT(args.length() == 2);
10016 HandleScope scope(isolate); 10029 HandleScope scope(isolate);
10017 CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0); 10030 CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0);
10018 CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]); 10031 CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]);
10019 if (array->elements()->IsDictionary()) { 10032 if (array->elements()->IsDictionary()) {
10020 // Create an array and get all the keys into it, then remove all the 10033 // Create an array and get all the keys into it, then remove all the
10021 // keys that are not integers in the range 0 to length-1. 10034 // keys that are not integers in the range 0 to length-1.
10022 bool threw = false; 10035 bool threw = false;
10023 Handle<FixedArray> keys = 10036 Handle<FixedArray> keys =
10024 GetKeysInFixedArrayFor(array, INCLUDE_PROTOS, &threw); 10037 GetKeysInFixedArrayFor<true>(array, INCLUDE_PROTOS, &threw);
10025 if (threw) return Failure::Exception(); 10038 if (threw) return Failure::Exception();
10026 10039
10027 int keys_length = keys->length(); 10040 int keys_length = keys->length();
10028 for (int i = 0; i < keys_length; i++) { 10041 for (int i = 0; i < keys_length; i++) {
10029 Object* key = keys->get(i); 10042 Object* key = keys->get(i);
10030 uint32_t index = 0; 10043 uint32_t index = 0;
10031 if (!key->ToArrayIndex(&index) || index >= length) { 10044 if (!key->ToArrayIndex(&index) || index >= length) {
10032 // Zap invalid keys. 10045 // Zap invalid keys.
10033 keys->set_undefined(i); 10046 keys->set_undefined(i);
10034 } 10047 }
(...skipping 794 matching lines...) Expand 10 before | Expand all | Expand 10 after
10829 } 10842 }
10830 10843
10831 // Finally copy any properties from the function context extension. 10844 // Finally copy any properties from the function context extension.
10832 // These will be variables introduced by eval. 10845 // These will be variables introduced by eval.
10833 if (function_context->closure() == *function) { 10846 if (function_context->closure() == *function) {
10834 if (function_context->has_extension() && 10847 if (function_context->has_extension() &&
10835 !function_context->IsNativeContext()) { 10848 !function_context->IsNativeContext()) {
10836 Handle<JSObject> ext(JSObject::cast(function_context->extension())); 10849 Handle<JSObject> ext(JSObject::cast(function_context->extension()));
10837 bool threw = false; 10850 bool threw = false;
10838 Handle<FixedArray> keys = 10851 Handle<FixedArray> keys =
10839 GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw); 10852 GetKeysInFixedArrayFor<true>(ext, INCLUDE_PROTOS, &threw);
10840 if (threw) return Handle<JSObject>(); 10853 if (threw) return Handle<JSObject>();
10841 10854
10842 for (int i = 0; i < keys->length(); i++) { 10855 for (int i = 0; i < keys->length(); i++) {
10843 // Names of variables introduced by eval are strings. 10856 // Names of variables introduced by eval are strings.
10844 ASSERT(keys->get(i)->IsString()); 10857 ASSERT(keys->get(i)->IsString());
10845 Handle<String> key(String::cast(keys->get(i))); 10858 Handle<String> key(String::cast(keys->get(i)));
10846 RETURN_IF_EMPTY_HANDLE_VALUE( 10859 RETURN_IF_EMPTY_HANDLE_VALUE(
10847 isolate, 10860 isolate,
10848 SetProperty(isolate, 10861 SetProperty(isolate,
10849 local_scope, 10862 local_scope,
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
10980 isolate, scope_info, context, closure_scope)) { 10993 isolate, scope_info, context, closure_scope)) {
10981 return Handle<JSObject>(); 10994 return Handle<JSObject>();
10982 } 10995 }
10983 10996
10984 // Finally copy any properties from the function context extension. This will 10997 // Finally copy any properties from the function context extension. This will
10985 // be variables introduced by eval. 10998 // be variables introduced by eval.
10986 if (context->has_extension()) { 10999 if (context->has_extension()) {
10987 Handle<JSObject> ext(JSObject::cast(context->extension())); 11000 Handle<JSObject> ext(JSObject::cast(context->extension()));
10988 bool threw = false; 11001 bool threw = false;
10989 Handle<FixedArray> keys = 11002 Handle<FixedArray> keys =
10990 GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw); 11003 GetKeysInFixedArrayFor<true>(ext, INCLUDE_PROTOS, &threw);
10991 if (threw) return Handle<JSObject>(); 11004 if (threw) return Handle<JSObject>();
10992 11005
10993 for (int i = 0; i < keys->length(); i++) { 11006 for (int i = 0; i < keys->length(); i++) {
10994 // Names of variables introduced by eval are strings. 11007 // Names of variables introduced by eval are strings.
10995 ASSERT(keys->get(i)->IsString()); 11008 ASSERT(keys->get(i)->IsString());
10996 Handle<String> key(String::cast(keys->get(i))); 11009 Handle<String> key(String::cast(keys->get(i)));
10997 RETURN_IF_EMPTY_HANDLE_VALUE( 11010 RETURN_IF_EMPTY_HANDLE_VALUE(
10998 isolate, 11011 isolate,
10999 SetProperty(isolate, 11012 SetProperty(isolate,
11000 closure_scope, 11013 closure_scope,
(...skipping 2070 matching lines...) Expand 10 before | Expand all | Expand 10 after
13071 CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0); 13084 CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
13072 HandleScope scope(isolate); 13085 HandleScope scope(isolate);
13073 Handle<String> key = isolate->factory()->hidden_stack_trace_symbol(); 13086 Handle<String> key = isolate->factory()->hidden_stack_trace_symbol();
13074 JSObject::SetHiddenProperty(fun, key, key); 13087 JSObject::SetHiddenProperty(fun, key, key);
13075 return *fun; 13088 return *fun;
13076 } 13089 }
13077 13090
13078 13091
13079 // Retrieve the stack trace. This could be the raw stack trace collected 13092 // Retrieve the stack trace. This could be the raw stack trace collected
13080 // on stack overflow or the already formatted stack trace string. 13093 // on stack overflow or the already formatted stack trace string.
13081 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOverflowedStackTrace) { 13094 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOverflowStackTrace) {
13082 HandleScope scope(isolate); 13095 HandleScope scope(isolate);
13083 ASSERT_EQ(args.length(), 1); 13096 ASSERT_EQ(args.length(), 1);
13084 CONVERT_ARG_CHECKED(JSObject, error_object, 0); 13097 CONVERT_ARG_CHECKED(JSObject, error_object, 0);
13085 String* key = isolate->heap()->hidden_stack_trace_symbol(); 13098 String* key = isolate->heap()->overflow_stack_trace_symbol();
13086 Object* result = error_object->GetHiddenProperty(key); 13099 Object* result = error_object->GetHiddenProperty(key);
13087 RUNTIME_ASSERT(result->IsJSArray() || 13100 RUNTIME_ASSERT(result->IsJSArray() ||
13088 result->IsString() || 13101 result->IsString() ||
13102 result->IsJSObject() ||
13089 result->IsUndefined()); 13103 result->IsUndefined());
13090 return result; 13104 return result;
13091 } 13105 }
13092 13106
13093 13107
13094 // Set or clear the stack trace attached to an stack overflow error object. 13108 // Set or clear the stack trace attached to an stack overflow error object.
13095 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetOverflowedStackTrace) { 13109 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetOverflowStackTrace) {
13096 HandleScope scope(isolate); 13110 HandleScope scope(isolate);
13097 ASSERT_EQ(args.length(), 2); 13111 ASSERT_EQ(args.length(), 2);
13098 CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0); 13112 CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
13099 CONVERT_ARG_HANDLE_CHECKED(HeapObject, value, 1); 13113 CONVERT_ARG_HANDLE_CHECKED(HeapObject, value, 1);
13100 Handle<String> key = isolate->factory()->hidden_stack_trace_symbol(); 13114 Handle<String> key = isolate->factory()->overflow_stack_trace_symbol();
13101 if (value->IsUndefined()) { 13115 if (value->IsUndefined()) {
13102 error_object->DeleteHiddenProperty(*key); 13116 error_object->DeleteHiddenProperty(*key);
13103 } else { 13117 } else {
13104 RUNTIME_ASSERT(value->IsString()); 13118 RUNTIME_ASSERT(value->IsString() || value->IsJSObject());
13105 JSObject::SetHiddenProperty(error_object, key, value); 13119 JSObject::SetHiddenProperty(error_object, key, value);
13106 } 13120 }
13107 return *error_object; 13121 return *error_object;
13108 } 13122 }
13109 13123
13110 13124
13111 // Returns V8 version as a string. 13125 // Returns V8 version as a string.
13112 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetV8Version) { 13126 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetV8Version) {
13113 ASSERT_EQ(args.length(), 0); 13127 ASSERT_EQ(args.length(), 0);
13114 13128
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
13519 // Handle last resort GC and make sure to allow future allocations 13533 // Handle last resort GC and make sure to allow future allocations
13520 // to grow the heap without causing GCs (if possible). 13534 // to grow the heap without causing GCs (if possible).
13521 isolate->counters()->gc_last_resort_from_js()->Increment(); 13535 isolate->counters()->gc_last_resort_from_js()->Increment();
13522 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 13536 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
13523 "Runtime::PerformGC"); 13537 "Runtime::PerformGC");
13524 } 13538 }
13525 } 13539 }
13526 13540
13527 13541
13528 } } // namespace v8::internal 13542 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime.h ('k') | test/cctest/cctest.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698