| OLD | NEW |
| 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 14 matching lines...) Expand all Loading... |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #include <stdlib.h> | 28 #include <stdlib.h> |
| 29 | 29 |
| 30 #include "v8.h" | 30 #include "v8.h" |
| 31 | 31 |
| 32 #include "accessors.h" | 32 #include "accessors.h" |
| 33 #include "api.h" | 33 #include "api.h" |
| 34 #include "arguments.h" | 34 #include "arguments.h" |
| 35 #include "bootstrapper.h" |
| 35 #include "compiler.h" | 36 #include "compiler.h" |
| 36 #include "cpu.h" | 37 #include "cpu.h" |
| 37 #include "dateparser-inl.h" | 38 #include "dateparser-inl.h" |
| 38 #include "debug.h" | 39 #include "debug.h" |
| 39 #include "execution.h" | 40 #include "execution.h" |
| 40 #include "jsregexp.h" | 41 #include "jsregexp.h" |
| 41 #include "parser.h" | 42 #include "parser.h" |
| 42 #include "platform.h" | 43 #include "platform.h" |
| 43 #include "runtime.h" | 44 #include "runtime.h" |
| 44 #include "scopeinfo.h" | 45 #include "scopeinfo.h" |
| (...skipping 4542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4587 WriteBarrierMode mode = array->GetWriteBarrierMode(); | 4588 WriteBarrierMode mode = array->GetWriteBarrierMode(); |
| 4588 for (int i = 0; i < length; i++) { | 4589 for (int i = 0; i < length; i++) { |
| 4589 array->set(i, *--parameters, mode); | 4590 array->set(i, *--parameters, mode); |
| 4590 } | 4591 } |
| 4591 JSObject::cast(result)->set_elements(FixedArray::cast(obj)); | 4592 JSObject::cast(result)->set_elements(FixedArray::cast(obj)); |
| 4592 } | 4593 } |
| 4593 return result; | 4594 return result; |
| 4594 } | 4595 } |
| 4595 | 4596 |
| 4596 | 4597 |
| 4598 |
| 4599 // We avoid inlining this function by placing it in another .cc file. |
| 4600 extern void CaptureInfoForIssue555( |
| 4601 bool is_bootstrapping, |
| 4602 AllocationSpace context_space, |
| 4603 Object* context, |
| 4604 Object* context_map, |
| 4605 int context_length, |
| 4606 Object* context_closure, |
| 4607 Object* context_fcontext, |
| 4608 Object* context_previous, |
| 4609 Object* context_extension, |
| 4610 Object* context_global, |
| 4611 AllocationSpace function_space, |
| 4612 Object* function, |
| 4613 bool runs_in_inner_context, |
| 4614 bool runs_in_outer_context); |
| 4615 |
| 4616 |
| 4617 static AllocationSpace ComputeSpace(Object* object) { |
| 4618 static const AllocationSpace kIllegalSpace = static_cast<AllocationSpace>(-1); |
| 4619 if (!object->IsHeapObject()) return kIllegalSpace; |
| 4620 for (int attempt = FIRST_SPACE; attempt <= LAST_SPACE; attempt++) { |
| 4621 AllocationSpace space = static_cast<AllocationSpace>(attempt); |
| 4622 if (Heap::InSpace(HeapObject::cast(object), space)) return space; |
| 4623 } |
| 4624 return kIllegalSpace; |
| 4625 } |
| 4626 |
| 4627 |
| 4628 static void DiagnoseIssue555(Arguments args) { |
| 4629 static const int kUninitialized = 0x12345678; |
| 4630 static Object* const kUninitializedObject = bit_cast<Object*>(kUninitialized); |
| 4631 |
| 4632 // Read the invalid context from the arguments. |
| 4633 Object* context = args[0]; |
| 4634 |
| 4635 // Compute basic diagnostic information. |
| 4636 bool is_bootstrapping = Bootstrapper::IsActive(); |
| 4637 AllocationSpace context_space = ComputeSpace(context); |
| 4638 |
| 4639 // Get the context map and length. |
| 4640 Object* context_map = kUninitializedObject; |
| 4641 int context_length = kUninitialized; |
| 4642 if (context->IsHeapObject()) { |
| 4643 context_map = HeapObject::cast(context)->map(); |
| 4644 context_length = FixedArray::cast(context)->length(); |
| 4645 } |
| 4646 |
| 4647 // Get the context slots. |
| 4648 Object* context_slots[Context::MIN_CONTEXT_SLOTS]; |
| 4649 for (int i = 0; i < Context::MIN_CONTEXT_SLOTS; i++) { |
| 4650 // Initialize the context slots to a recognizable bit pattern. |
| 4651 context_slots[i] = kUninitializedObject; |
| 4652 if (context->IsHeapObject()) { |
| 4653 context_slots[i] = FixedArray::cast(context)->get(i); |
| 4654 } |
| 4655 } |
| 4656 |
| 4657 // Check if the function that requested a new closure runs either in |
| 4658 // its outer context (set in the function) or in its own dynamically |
| 4659 // created inner context. |
| 4660 StackFrameLocator locator; |
| 4661 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); |
| 4662 JSFunction* function = JSFunction::cast(frame->function()); |
| 4663 AllocationSpace function_space = ComputeSpace(function); |
| 4664 bool runs_in_inner_context = |
| 4665 (function == context_slots[Context::CLOSURE_INDEX]); |
| 4666 bool runs_in_outer_context = |
| 4667 (function->context() == context); |
| 4668 |
| 4669 // Capture the diagnostic information by passing the state to an |
| 4670 // external function. |
| 4671 CaptureInfoForIssue555( |
| 4672 is_bootstrapping, |
| 4673 context_space, |
| 4674 context, |
| 4675 context_map, |
| 4676 context_length, |
| 4677 context_slots[Context::CLOSURE_INDEX], |
| 4678 context_slots[Context::FCONTEXT_INDEX], |
| 4679 context_slots[Context::PREVIOUS_INDEX], |
| 4680 context_slots[Context::EXTENSION_INDEX], |
| 4681 context_slots[Context::GLOBAL_INDEX], |
| 4682 function_space, |
| 4683 function, |
| 4684 runs_in_inner_context, |
| 4685 runs_in_outer_context); |
| 4686 } |
| 4687 |
| 4688 |
| 4597 static Object* Runtime_NewClosure(Arguments args) { | 4689 static Object* Runtime_NewClosure(Arguments args) { |
| 4598 HandleScope scope; | 4690 HandleScope scope; |
| 4599 ASSERT(args.length() == 2); | 4691 ASSERT(args.length() == 2); |
| 4692 |
| 4693 // BUG(555): Attempt to gather more information about the crash in |
| 4694 // NewClosure where the context is invalid. This rarely happens, but |
| 4695 // it brings down V8 through a null pointer exception when throwing |
| 4696 // an illegal access exception. For more details, see: |
| 4697 // http://code.google.com/p/v8/issues/detail?id=555 |
| 4698 if (!args[0]->IsContext()) DiagnoseIssue555(args); |
| 4699 |
| 4600 CONVERT_ARG_CHECKED(Context, context, 0); | 4700 CONVERT_ARG_CHECKED(Context, context, 0); |
| 4601 CONVERT_ARG_CHECKED(JSFunction, boilerplate, 1); | 4701 CONVERT_ARG_CHECKED(JSFunction, boilerplate, 1); |
| 4602 | 4702 |
| 4603 PretenureFlag pretenure = (context->global_context() == *context) | 4703 PretenureFlag pretenure = (context->global_context() == *context) |
| 4604 ? TENURED // Allocate global closures in old space. | 4704 ? TENURED // Allocate global closures in old space. |
| 4605 : NOT_TENURED; // Allocate local closures in new space. | 4705 : NOT_TENURED; // Allocate local closures in new space. |
| 4606 Handle<JSFunction> result = | 4706 Handle<JSFunction> result = |
| 4607 Factory::NewFunctionFromBoilerplate(boilerplate, context, pretenure); | 4707 Factory::NewFunctionFromBoilerplate(boilerplate, context, pretenure); |
| 4608 return *result; | 4708 return *result; |
| 4609 } | 4709 } |
| (...skipping 3544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8154 } else { | 8254 } else { |
| 8155 // Handle last resort GC and make sure to allow future allocations | 8255 // Handle last resort GC and make sure to allow future allocations |
| 8156 // to grow the heap without causing GCs (if possible). | 8256 // to grow the heap without causing GCs (if possible). |
| 8157 Counters::gc_last_resort_from_js.Increment(); | 8257 Counters::gc_last_resort_from_js.Increment(); |
| 8158 Heap::CollectAllGarbage(false); | 8258 Heap::CollectAllGarbage(false); |
| 8159 } | 8259 } |
| 8160 } | 8260 } |
| 8161 | 8261 |
| 8162 | 8262 |
| 8163 } } // namespace v8::internal | 8263 } } // namespace v8::internal |
| OLD | NEW |