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 4937 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4948 | 4948 |
4949 void SharedFunctionInfo::SharedFunctionInfoIterateBody(ObjectVisitor* v) { | 4949 void SharedFunctionInfo::SharedFunctionInfoIterateBody(ObjectVisitor* v) { |
4950 IteratePointers(v, kNameOffset, kConstructStubOffset + kPointerSize); | 4950 IteratePointers(v, kNameOffset, kConstructStubOffset + kPointerSize); |
4951 IteratePointers(v, kInstanceClassNameOffset, kScriptOffset + kPointerSize); | 4951 IteratePointers(v, kInstanceClassNameOffset, kScriptOffset + kPointerSize); |
4952 IteratePointers(v, kDebugInfoOffset, kInferredNameOffset + kPointerSize); | 4952 IteratePointers(v, kDebugInfoOffset, kInferredNameOffset + kPointerSize); |
4953 IteratePointers(v, kThisPropertyAssignmentsOffset, | 4953 IteratePointers(v, kThisPropertyAssignmentsOffset, |
4954 kThisPropertyAssignmentsOffset + kPointerSize); | 4954 kThisPropertyAssignmentsOffset + kPointerSize); |
4955 } | 4955 } |
4956 | 4956 |
4957 | 4957 |
4958 void ObjectVisitor::BeginCodeIteration(Code* code) { | |
4959 ASSERT(code->ic_flag() == Code::IC_TARGET_IS_OBJECT); | |
4960 } | |
4961 | |
4962 | |
4963 void ObjectVisitor::VisitCodeTarget(RelocInfo* rinfo) { | 4958 void ObjectVisitor::VisitCodeTarget(RelocInfo* rinfo) { |
4964 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); | 4959 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); |
4965 VisitPointer(rinfo->target_object_address()); | 4960 Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); |
| 4961 Object* old_target = target; |
| 4962 VisitPointer(&target); |
| 4963 CHECK_EQ(target, old_target); // VisitPointer doesn't change Code* *target. |
4966 } | 4964 } |
4967 | 4965 |
4968 | 4966 |
4969 void ObjectVisitor::VisitDebugTarget(RelocInfo* rinfo) { | 4967 void ObjectVisitor::VisitDebugTarget(RelocInfo* rinfo) { |
4970 ASSERT(RelocInfo::IsJSReturn(rinfo->rmode()) && rinfo->IsCallInstruction()); | 4968 ASSERT(RelocInfo::IsJSReturn(rinfo->rmode()) && rinfo->IsCallInstruction()); |
4971 VisitPointer(rinfo->call_object_address()); | 4969 Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address()); |
4972 } | 4970 Object* old_target = target; |
4973 | 4971 VisitPointer(&target); |
4974 | 4972 CHECK_EQ(target, old_target); // VisitPointer doesn't change Code* *target. |
4975 // Convert relocatable targets from address to code object address. This is | |
4976 // mainly IC call targets but for debugging straight-line code can be replaced | |
4977 // with a call instruction which also has to be relocated. | |
4978 void Code::ConvertICTargetsFromAddressToObject() { | |
4979 ASSERT(ic_flag() == IC_TARGET_IS_ADDRESS); | |
4980 | |
4981 for (RelocIterator it(this, RelocInfo::kCodeTargetMask); | |
4982 !it.done(); it.next()) { | |
4983 Address ic_addr = it.rinfo()->target_address(); | |
4984 ASSERT(ic_addr != NULL); | |
4985 HeapObject* code = Code::GetCodeFromTargetAddress(ic_addr); | |
4986 ASSERT(code->IsHeapObject()); | |
4987 it.rinfo()->set_target_object(code); | |
4988 } | |
4989 | |
4990 #ifdef ENABLE_DEBUGGER_SUPPORT | |
4991 if (Debug::has_break_points()) { | |
4992 for (RelocIterator it(this, RelocInfo::ModeMask(RelocInfo::JS_RETURN)); | |
4993 !it.done(); | |
4994 it.next()) { | |
4995 if (it.rinfo()->IsCallInstruction()) { | |
4996 Address addr = it.rinfo()->call_address(); | |
4997 ASSERT(addr != NULL); | |
4998 HeapObject* code = Code::GetCodeFromTargetAddress(addr); | |
4999 ASSERT(code->IsHeapObject()); | |
5000 it.rinfo()->set_call_object(code); | |
5001 } | |
5002 } | |
5003 } | |
5004 #endif | |
5005 set_ic_flag(IC_TARGET_IS_OBJECT); | |
5006 } | 4973 } |
5007 | 4974 |
5008 | 4975 |
5009 void Code::CodeIterateBody(ObjectVisitor* v) { | 4976 void Code::CodeIterateBody(ObjectVisitor* v) { |
5010 v->BeginCodeIteration(this); | |
5011 | |
5012 int mode_mask = RelocInfo::kCodeTargetMask | | 4977 int mode_mask = RelocInfo::kCodeTargetMask | |
5013 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) | | 4978 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) | |
5014 RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) | | 4979 RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) | |
5015 RelocInfo::ModeMask(RelocInfo::JS_RETURN) | | 4980 RelocInfo::ModeMask(RelocInfo::JS_RETURN) | |
5016 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY); | 4981 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY); |
5017 | 4982 |
5018 for (RelocIterator it(this, mode_mask); !it.done(); it.next()) { | 4983 for (RelocIterator it(this, mode_mask); !it.done(); it.next()) { |
5019 RelocInfo::Mode rmode = it.rinfo()->rmode(); | 4984 RelocInfo::Mode rmode = it.rinfo()->rmode(); |
5020 if (rmode == RelocInfo::EMBEDDED_OBJECT) { | 4985 if (rmode == RelocInfo::EMBEDDED_OBJECT) { |
5021 v->VisitPointer(it.rinfo()->target_object_address()); | 4986 v->VisitPointer(it.rinfo()->target_object_address()); |
5022 } else if (RelocInfo::IsCodeTarget(rmode)) { | 4987 } else if (RelocInfo::IsCodeTarget(rmode)) { |
5023 v->VisitCodeTarget(it.rinfo()); | 4988 v->VisitCodeTarget(it.rinfo()); |
5024 } else if (rmode == RelocInfo::EXTERNAL_REFERENCE) { | 4989 } else if (rmode == RelocInfo::EXTERNAL_REFERENCE) { |
5025 v->VisitExternalReference(it.rinfo()->target_reference_address()); | 4990 v->VisitExternalReference(it.rinfo()->target_reference_address()); |
5026 #ifdef ENABLE_DEBUGGER_SUPPORT | 4991 #ifdef ENABLE_DEBUGGER_SUPPORT |
5027 } else if (Debug::has_break_points() && | 4992 } else if (Debug::has_break_points() && |
5028 RelocInfo::IsJSReturn(rmode) && | 4993 RelocInfo::IsJSReturn(rmode) && |
5029 it.rinfo()->IsCallInstruction()) { | 4994 it.rinfo()->IsCallInstruction()) { |
5030 v->VisitDebugTarget(it.rinfo()); | 4995 v->VisitDebugTarget(it.rinfo()); |
5031 #endif | 4996 #endif |
5032 } else if (rmode == RelocInfo::RUNTIME_ENTRY) { | 4997 } else if (rmode == RelocInfo::RUNTIME_ENTRY) { |
5033 v->VisitRuntimeEntry(it.rinfo()); | 4998 v->VisitRuntimeEntry(it.rinfo()); |
5034 } | 4999 } |
5035 } | 5000 } |
5036 | 5001 |
5037 ScopeInfo<>::IterateScopeInfo(this, v); | 5002 ScopeInfo<>::IterateScopeInfo(this, v); |
5038 | |
5039 v->EndCodeIteration(this); | |
5040 } | |
5041 | |
5042 | |
5043 void Code::ConvertICTargetsFromObjectToAddress() { | |
5044 ASSERT(ic_flag() == IC_TARGET_IS_OBJECT); | |
5045 | |
5046 for (RelocIterator it(this, RelocInfo::kCodeTargetMask); | |
5047 !it.done(); it.next()) { | |
5048 // We cannot use the safe cast (Code::cast) here, because we may be in | |
5049 // the middle of relocating old objects during GC and the map pointer in | |
5050 // the code object may be mangled | |
5051 Code* code = reinterpret_cast<Code*>(it.rinfo()->target_object()); | |
5052 ASSERT((code != NULL) && code->IsHeapObject()); | |
5053 it.rinfo()->set_target_address(code->instruction_start()); | |
5054 } | |
5055 | |
5056 #ifdef ENABLE_DEBUGGER_SUPPORT | |
5057 if (Debug::has_break_points()) { | |
5058 for (RelocIterator it(this, RelocInfo::ModeMask(RelocInfo::JS_RETURN)); | |
5059 !it.done(); | |
5060 it.next()) { | |
5061 if (it.rinfo()->IsCallInstruction()) { | |
5062 Code* code = reinterpret_cast<Code*>(it.rinfo()->call_object()); | |
5063 ASSERT((code != NULL) && code->IsHeapObject()); | |
5064 it.rinfo()->set_call_address(code->instruction_start()); | |
5065 } | |
5066 } | |
5067 } | |
5068 #endif | |
5069 set_ic_flag(IC_TARGET_IS_ADDRESS); | |
5070 } | 5003 } |
5071 | 5004 |
5072 | 5005 |
5073 void Code::Relocate(int delta) { | 5006 void Code::Relocate(int delta) { |
5074 for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) { | 5007 for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) { |
5075 it.rinfo()->apply(delta); | 5008 it.rinfo()->apply(delta); |
5076 } | 5009 } |
5077 CPU::FlushICache(instruction_start(), instruction_size()); | 5010 CPU::FlushICache(instruction_start(), instruction_size()); |
5078 } | 5011 } |
5079 | 5012 |
(...skipping 2950 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8030 if (break_point_objects()->IsUndefined()) return 0; | 7963 if (break_point_objects()->IsUndefined()) return 0; |
8031 // Single beak point. | 7964 // Single beak point. |
8032 if (!break_point_objects()->IsFixedArray()) return 1; | 7965 if (!break_point_objects()->IsFixedArray()) return 1; |
8033 // Multiple break points. | 7966 // Multiple break points. |
8034 return FixedArray::cast(break_point_objects())->length(); | 7967 return FixedArray::cast(break_point_objects())->length(); |
8035 } | 7968 } |
8036 #endif | 7969 #endif |
8037 | 7970 |
8038 | 7971 |
8039 } } // namespace v8::internal | 7972 } } // namespace v8::internal |
OLD | NEW |