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

Side by Side Diff: src/runtime.cc

Issue 3499001: Fix more GC unsafe places (Closed)
Patch Set: fix Vitaly's comment Created 10 years, 3 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
« no previous file with comments | « src/debug.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 620 matching lines...) Expand 10 before | Expand all | Expand 10 after
631 // if args[1] is a data property on args[0] 631 // if args[1] is a data property on args[0]
632 // [false, value, Writeable, Enumerable, Configurable] 632 // [false, value, Writeable, Enumerable, Configurable]
633 // if args[1] is an accessor on args[0] 633 // if args[1] is an accessor on args[0]
634 // [true, GetFunction, SetFunction, Enumerable, Configurable] 634 // [true, GetFunction, SetFunction, Enumerable, Configurable]
635 static Object* Runtime_GetOwnProperty(Arguments args) { 635 static Object* Runtime_GetOwnProperty(Arguments args) {
636 ASSERT(args.length() == 2); 636 ASSERT(args.length() == 2);
637 HandleScope scope; 637 HandleScope scope;
638 Handle<FixedArray> elms = Factory::NewFixedArray(DESCRIPTOR_SIZE); 638 Handle<FixedArray> elms = Factory::NewFixedArray(DESCRIPTOR_SIZE);
639 Handle<JSArray> desc = Factory::NewJSArrayWithElements(elms); 639 Handle<JSArray> desc = Factory::NewJSArrayWithElements(elms);
640 LookupResult result; 640 LookupResult result;
641 CONVERT_CHECKED(JSObject, obj, args[0]); 641 CONVERT_ARG_CHECKED(JSObject, obj, 0);
642 CONVERT_CHECKED(String, name, args[1]); 642 CONVERT_ARG_CHECKED(String, name, 1);
643 643
644 // This could be an element. 644 // This could be an element.
645 uint32_t index; 645 uint32_t index;
646 if (name->AsArrayIndex(&index)) { 646 if (name->AsArrayIndex(&index)) {
647 switch (obj->HasLocalElement(index)) { 647 switch (obj->HasLocalElement(index)) {
648 case JSObject::UNDEFINED_ELEMENT: 648 case JSObject::UNDEFINED_ELEMENT:
649 return Heap::undefined_value(); 649 return Heap::undefined_value();
650 650
651 case JSObject::STRING_CHARACTER_ELEMENT: { 651 case JSObject::STRING_CHARACTER_ELEMENT: {
652 // Special handling of string objects according to ECMAScript 5 652 // Special handling of string objects according to ECMAScript 5
653 // 15.5.5.2. Note that this might be a string object with elements 653 // 15.5.5.2. Note that this might be a string object with elements
654 // other than the actual string value. This is covered by the 654 // other than the actual string value. This is covered by the
655 // subsequent cases. 655 // subsequent cases.
656 JSValue* js_value = JSValue::cast(obj); 656 Handle<JSValue> js_value = Handle<JSValue>::cast(obj);
657 String* str = String::cast(js_value->value()); 657 Handle<String> str(String::cast(js_value->value()));
658 Handle<String> substr = SubString(str, index, index+1, NOT_TENURED);
659
658 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); 660 elms->set(IS_ACCESSOR_INDEX, Heap::false_value());
659 elms->set(VALUE_INDEX, str->SubString(index, index+1)); 661 elms->set(VALUE_INDEX, *substr);
660 elms->set(WRITABLE_INDEX, Heap::false_value()); 662 elms->set(WRITABLE_INDEX, Heap::false_value());
661 elms->set(ENUMERABLE_INDEX, Heap::false_value()); 663 elms->set(ENUMERABLE_INDEX, Heap::false_value());
662 elms->set(CONFIGURABLE_INDEX, Heap::false_value()); 664 elms->set(CONFIGURABLE_INDEX, Heap::false_value());
663 return *desc; 665 return *desc;
664 } 666 }
665 667
666 case JSObject::INTERCEPTED_ELEMENT: 668 case JSObject::INTERCEPTED_ELEMENT:
667 case JSObject::FAST_ELEMENT: 669 case JSObject::FAST_ELEMENT: {
668 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); 670 elms->set(IS_ACCESSOR_INDEX, Heap::false_value());
669 elms->set(VALUE_INDEX, obj->GetElement(index)); 671 Handle<Object> element = GetElement(Handle<Object>(obj), index);
672 elms->set(VALUE_INDEX, *element);
670 elms->set(WRITABLE_INDEX, Heap::true_value()); 673 elms->set(WRITABLE_INDEX, Heap::true_value());
671 elms->set(ENUMERABLE_INDEX, Heap::true_value()); 674 elms->set(ENUMERABLE_INDEX, Heap::true_value());
672 elms->set(CONFIGURABLE_INDEX, Heap::true_value()); 675 elms->set(CONFIGURABLE_INDEX, Heap::true_value());
673 return *desc; 676 return *desc;
677 }
674 678
675 case JSObject::DICTIONARY_ELEMENT: { 679 case JSObject::DICTIONARY_ELEMENT: {
676 NumberDictionary* dictionary = obj->element_dictionary(); 680 NumberDictionary* dictionary = obj->element_dictionary();
677 int entry = dictionary->FindEntry(index); 681 int entry = dictionary->FindEntry(index);
678 ASSERT(entry != NumberDictionary::kNotFound); 682 ASSERT(entry != NumberDictionary::kNotFound);
679 PropertyDetails details = dictionary->DetailsAt(entry); 683 PropertyDetails details = dictionary->DetailsAt(entry);
680 switch (details.type()) { 684 switch (details.type()) {
681 case CALLBACKS: { 685 case CALLBACKS: {
682 // This is an accessor property with getter and/or setter. 686 // This is an accessor property with getter and/or setter.
683 FixedArray* callbacks = 687 FixedArray* callbacks =
(...skipping 14 matching lines...) Expand all
698 break; 702 break;
699 } 703 }
700 elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!details.IsDontEnum())); 704 elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!details.IsDontEnum()));
701 elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!details.IsDontDelete())); 705 elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!details.IsDontDelete()));
702 return *desc; 706 return *desc;
703 } 707 }
704 } 708 }
705 } 709 }
706 710
707 // Use recursive implementation to also traverse hidden prototypes 711 // Use recursive implementation to also traverse hidden prototypes
708 GetOwnPropertyImplementation(obj, name, &result); 712 GetOwnPropertyImplementation(*obj, *name, &result);
709 713
710 if (!result.IsProperty()) { 714 if (!result.IsProperty()) {
711 return Heap::undefined_value(); 715 return Heap::undefined_value();
712 } 716 }
713 if (result.type() == CALLBACKS) { 717 if (result.type() == CALLBACKS) {
714 Object* structure = result.GetCallbackObject(); 718 Object* structure = result.GetCallbackObject();
715 if (structure->IsProxy() || structure->IsAccessorInfo()) { 719 if (structure->IsProxy() || structure->IsAccessorInfo()) {
716 // Property that is internally implemented as a callback or 720 // Property that is internally implemented as a callback or
717 // an API defined callback. 721 // an API defined callback.
718 Object* value = obj->GetPropertyWithCallback( 722 Object* value = obj->GetPropertyWithCallback(
719 obj, structure, name, result.holder()); 723 *obj, structure, *name, result.holder());
724 if (value->IsFailure()) return value;
720 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); 725 elms->set(IS_ACCESSOR_INDEX, Heap::false_value());
721 elms->set(VALUE_INDEX, value); 726 elms->set(VALUE_INDEX, value);
722 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!result.IsReadOnly())); 727 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!result.IsReadOnly()));
723 } else if (structure->IsFixedArray()) { 728 } else if (structure->IsFixedArray()) {
724 // __defineGetter__/__defineSetter__ callback. 729 // __defineGetter__/__defineSetter__ callback.
725 elms->set(IS_ACCESSOR_INDEX, Heap::true_value()); 730 elms->set(IS_ACCESSOR_INDEX, Heap::true_value());
726 elms->set(GETTER_INDEX, FixedArray::cast(structure)->get(0)); 731 elms->set(GETTER_INDEX, FixedArray::cast(structure)->get(0));
727 elms->set(SETTER_INDEX, FixedArray::cast(structure)->get(1)); 732 elms->set(SETTER_INDEX, FixedArray::cast(structure)->get(1));
728 } else { 733 } else {
729 return Heap::undefined_value(); 734 return Heap::undefined_value();
(...skipping 6800 matching lines...) Expand 10 before | Expand all | Expand 10 after
7530 // If estimated number of elements is more than half of length, a 7535 // If estimated number of elements is more than half of length, a
7531 // fixed array (fast case) is more time and space-efficient than a 7536 // fixed array (fast case) is more time and space-efficient than a
7532 // dictionary. 7537 // dictionary.
7533 bool fast_case = (estimate_nof_elements * 2) >= result_length; 7538 bool fast_case = (estimate_nof_elements * 2) >= result_length;
7534 7539
7535 Handle<FixedArray> storage; 7540 Handle<FixedArray> storage;
7536 if (fast_case) { 7541 if (fast_case) {
7537 // The backing storage array must have non-existing elements to 7542 // The backing storage array must have non-existing elements to
7538 // preserve holes across concat operations. 7543 // preserve holes across concat operations.
7539 storage = Factory::NewFixedArrayWithHoles(result_length); 7544 storage = Factory::NewFixedArrayWithHoles(result_length);
7540 result->set_map(*Factory::GetFastElementsMap(Handle<Map>(result->map()))); 7545 Handle<Map> fast_map =
7546 Factory::GetFastElementsMap(Handle<Map>(result->map()));
7547 result->set_map(*fast_map);
7541 } else { 7548 } else {
7542 // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate 7549 // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate
7543 uint32_t at_least_space_for = estimate_nof_elements + 7550 uint32_t at_least_space_for = estimate_nof_elements +
7544 (estimate_nof_elements >> 2); 7551 (estimate_nof_elements >> 2);
7545 storage = Handle<FixedArray>::cast( 7552 storage = Handle<FixedArray>::cast(
7546 Factory::NewNumberDictionary(at_least_space_for)); 7553 Factory::NewNumberDictionary(at_least_space_for));
7547 result->set_map(*Factory::GetSlowElementsMap(Handle<Map>(result->map()))); 7554 Handle<Map> slow_map =
7555 Factory::GetSlowElementsMap(Handle<Map>(result->map()));
7556 result->set_map(*slow_map);
7548 } 7557 }
7549 7558
7550 Handle<Object> len = Factory::NewNumber(static_cast<double>(result_length)); 7559 Handle<Object> len = Factory::NewNumber(static_cast<double>(result_length));
7551 7560
7552 ArrayConcatVisitor visitor(storage, result_length, fast_case); 7561 ArrayConcatVisitor visitor(storage, result_length, fast_case);
7553 7562
7554 IterateArguments(arguments, &visitor); 7563 IterateArguments(arguments, &visitor);
7555 7564
7556 result->set_length(*len); 7565 result->set_length(*len);
7557 // Please note the storage might have changed in the visitor. 7566 // Please note the storage might have changed in the visitor.
(...skipping 1514 matching lines...) Expand 10 before | Expand all | Expand 10 after
9072 static Handle<Context> CopyWithContextChain(Handle<Context> context_chain, 9081 static Handle<Context> CopyWithContextChain(Handle<Context> context_chain,
9073 Handle<Context> function_context) { 9082 Handle<Context> function_context) {
9074 // At the bottom of the chain. Return the function context to link to. 9083 // At the bottom of the chain. Return the function context to link to.
9075 if (context_chain->is_function_context()) { 9084 if (context_chain->is_function_context()) {
9076 return function_context; 9085 return function_context;
9077 } 9086 }
9078 9087
9079 // Recursively copy the with contexts. 9088 // Recursively copy the with contexts.
9080 Handle<Context> previous(context_chain->previous()); 9089 Handle<Context> previous(context_chain->previous());
9081 Handle<JSObject> extension(JSObject::cast(context_chain->extension())); 9090 Handle<JSObject> extension(JSObject::cast(context_chain->extension()));
9082 return Factory::NewWithContext( 9091 Handle<Context> context = CopyWithContextChain(function_context, previous);
9083 CopyWithContextChain(function_context, previous), 9092 return Factory::NewWithContext(context,
9084 extension, 9093 extension,
9085 context_chain->IsCatchContext()); 9094 context_chain->IsCatchContext());
9086 } 9095 }
9087 9096
9088 9097
9089 // Helper function to find or create the arguments object for 9098 // Helper function to find or create the arguments object for
9090 // Runtime_DebugEvaluate. 9099 // Runtime_DebugEvaluate.
9091 static Handle<Object> GetArgumentsObject(JavaScriptFrame* frame, 9100 static Handle<Object> GetArgumentsObject(JavaScriptFrame* frame,
9092 Handle<JSFunction> function, 9101 Handle<JSFunction> function,
9093 Handle<SerializedScopeInfo> scope_info, 9102 Handle<SerializedScopeInfo> scope_info,
9094 const ScopeInfo<>* sinfo, 9103 const ScopeInfo<>* sinfo,
9095 Handle<Context> function_context) { 9104 Handle<Context> function_context) {
(...skipping 1108 matching lines...) Expand 10 before | Expand all | Expand 10 after
10204 } else { 10213 } else {
10205 // Handle last resort GC and make sure to allow future allocations 10214 // Handle last resort GC and make sure to allow future allocations
10206 // to grow the heap without causing GCs (if possible). 10215 // to grow the heap without causing GCs (if possible).
10207 Counters::gc_last_resort_from_js.Increment(); 10216 Counters::gc_last_resort_from_js.Increment();
10208 Heap::CollectAllGarbage(false); 10217 Heap::CollectAllGarbage(false);
10209 } 10218 }
10210 } 10219 }
10211 10220
10212 10221
10213 } } // namespace v8::internal 10222 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/debug.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698