| 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 |