Revision: 5309
Author: [email protected]
Date: Fri Aug 20 00:10:18 2010
Log: Change code pointer in function objects to a pointer to the first
instruction.
By changing the pointer to the code object to a pointer to the first
instruction we can call directly this instruction directly instead of
looking up the address through the code object.
Review URL: http://codereview.chromium.org/3156028
http://code.google.com/p/v8/source/detail?r=5309
Modified:
/branches/bleeding_edge/src/arm/builtins-arm.cc
/branches/bleeding_edge/src/arm/codegen-arm.cc
/branches/bleeding_edge/src/arm/macro-assembler-arm.cc
/branches/bleeding_edge/src/arm/macro-assembler-arm.h
/branches/bleeding_edge/src/ia32/builtins-ia32.cc
/branches/bleeding_edge/src/ia32/codegen-ia32.cc
/branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc
/branches/bleeding_edge/src/ia32/macro-assembler-ia32.h
/branches/bleeding_edge/src/liveedit.cc
/branches/bleeding_edge/src/mark-compact.cc
/branches/bleeding_edge/src/objects-inl.h
/branches/bleeding_edge/src/objects.cc
/branches/bleeding_edge/src/objects.h
/branches/bleeding_edge/src/serialize.cc
/branches/bleeding_edge/src/serialize.h
/branches/bleeding_edge/src/x64/builtins-x64.cc
/branches/bleeding_edge/src/x64/codegen-x64.cc
/branches/bleeding_edge/src/x64/macro-assembler-x64.cc
/branches/bleeding_edge/src/x64/macro-assembler-x64.h
=======================================
--- /branches/bleeding_edge/src/arm/builtins-arm.cc Wed Aug 11 06:48:58 2010
+++ /branches/bleeding_edge/src/arm/builtins-arm.cc Fri Aug 20 00:10:18 2010
@@ -1073,8 +1073,7 @@
__ ldr(r2,
FieldMemOperand(r3,
SharedFunctionInfo::kFormalParameterCountOffset));
__ mov(r2, Operand(r2, ASR, kSmiTagSize));
- __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeOffset));
- __ add(r3, r3, Operand(Code::kHeaderSize - kHeapObjectTag));
+ __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
__ cmp(r2, r0); // Check formal and actual parameter counts.
__ Jump(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)),
RelocInfo::CODE_TARGET, ne);
=======================================
--- /branches/bleeding_edge/src/arm/codegen-arm.cc Mon Aug 16 09:06:46 2010
+++ /branches/bleeding_edge/src/arm/codegen-arm.cc Fri Aug 20 00:10:18 2010
@@ -1556,7 +1556,8 @@
__ CompareObjectType(r0, r1, r2, JS_FUNCTION_TYPE);
__ b(ne, &build_args);
Handle<Code> apply_code(Builtins::builtin(Builtins::FunctionApply));
- __ ldr(r1, FieldMemOperand(r0, JSFunction::kCodeOffset));
+ __ ldr(r1, FieldMemOperand(r0, JSFunction::kCodeEntryOffset));
+ __ sub(r1, r1, Operand(Code::kHeaderSize - kHeapObjectTag));
__ cmp(r1, Operand(apply_code));
__ b(ne, &build_args);
@@ -7028,7 +7029,8 @@
// Initialize the code pointer in the function to be the one
// found in the shared function info object.
__ ldr(r3, FieldMemOperand(r3, SharedFunctionInfo::kCodeOffset));
- __ str(r3, FieldMemOperand(r0, JSFunction::kCodeOffset));
+ __ add(r3, r3, Operand(Code::kHeaderSize - kHeapObjectTag));
+ __ str(r3, FieldMemOperand(r0, JSFunction::kCodeEntryOffset));
// Return result. The argument function info has been popped already.
__ Ret();
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Mon Aug 16
09:06:46 2010
+++ /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Fri Aug 20
00:10:18 2010
@@ -757,8 +757,7 @@
SharedFunctionInfo::kFormalParameterCountOffset));
mov(expected_reg, Operand(expected_reg, ASR, kSmiTagSize));
ldr(code_reg,
- MemOperand(r1, JSFunction::kCodeOffset - kHeapObjectTag));
- add(code_reg, code_reg, Operand(Code::kHeaderSize - kHeapObjectTag));
+ FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
ParameterCount expected(expected_reg);
InvokeCode(code_reg, expected, actual, flag);
@@ -1490,30 +1489,22 @@
}
-void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript
id) {
- ASSERT(!target.is(r1));
-
+void MacroAssembler::GetBuiltinFunction(Register target,
+ Builtins::JavaScript id) {
// Load the builtins object into target register.
ldr(target, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
ldr(target, FieldMemOperand(target, GlobalObject::kBuiltinsOffset));
-
// Load the JavaScript builtin function from the builtins object.
- ldr(r1, FieldMemOperand(target,
+ ldr(target, FieldMemOperand(target,
JSBuiltinsObject::OffsetOfFunctionWithId(id)));
-
+}
+
+
+void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript
id) {
+ ASSERT(!target.is(r1));
+ GetBuiltinFunction(r1, id);
// Load the code entry point from the builtins object.
- ldr(target, FieldMemOperand(target,
- JSBuiltinsObject::OffsetOfCodeWithId(id)));
- if (FLAG_debug_code) {
- // Make sure the code objects in the builtins object and in the
- // builtin function are the same.
- push(r1);
- ldr(r1, FieldMemOperand(r1, JSFunction::kCodeOffset));
- cmp(r1, target);
- Assert(eq, "Builtin code object changed");
- pop(r1);
- }
- add(target, target, Operand(Code::kHeaderSize - kHeapObjectTag));
+ ldr(target, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
}
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.h Mon Aug 16
09:06:46 2010
+++ /branches/bleeding_edge/src/arm/macro-assembler-arm.h Fri Aug 20
00:10:18 2010
@@ -576,6 +576,9 @@
// setup the function in r1.
void GetBuiltinEntry(Register target, Builtins::JavaScript id);
+ // Store the function for the given builtin in the target register.
+ void GetBuiltinFunction(Register target, Builtins::JavaScript id);
+
Handle<Object> CodeObject() { return code_object_; }
=======================================
--- /branches/bleeding_edge/src/ia32/builtins-ia32.cc Wed Aug 11 06:48:58
2010
+++ /branches/bleeding_edge/src/ia32/builtins-ia32.cc Fri Aug 20 00:10:18
2010
@@ -567,9 +567,8 @@
__ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
__ mov(ebx,
FieldOperand(edx,
SharedFunctionInfo::kFormalParameterCountOffset));
+ __ mov(edx, FieldOperand(edi, JSFunction::kCodeEntryOffset));
__ SmiUntag(ebx);
- __ mov(edx, FieldOperand(edi, JSFunction::kCodeOffset));
- __ lea(edx, FieldOperand(edx, Code::kHeaderSize));
__ cmp(eax, Operand(ebx));
__ j(not_equal, Handle<Code>(builtin(ArgumentsAdaptorTrampoline)));
=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.cc Mon Aug 16 09:06:46
2010
+++ /branches/bleeding_edge/src/ia32/codegen-ia32.cc Fri Aug 20 00:10:18
2010
@@ -3423,8 +3423,10 @@
__ j(zero, &build_args);
__ CmpObjectType(eax, JS_FUNCTION_TYPE, ecx);
__ j(not_equal, &build_args);
+ __ mov(ecx, FieldOperand(eax, JSFunction::kCodeEntryOffset));
+ __ sub(Operand(ecx), Immediate(Code::kHeaderSize - kHeapObjectTag));
Handle<Code> apply_code(Builtins::builtin(Builtins::FunctionApply));
- __ cmp(FieldOperand(eax, JSFunction::kCodeOffset),
Immediate(apply_code));
+ __ cmp(Operand(ecx), Immediate(apply_code));
__ j(not_equal, &build_args);
// Check that applicand is a function.
@@ -9815,7 +9817,8 @@
// Initialize the code pointer in the function to be the one
// found in the shared function info object.
__ mov(edx, FieldOperand(edx, SharedFunctionInfo::kCodeOffset));
- __ mov(FieldOperand(eax, JSFunction::kCodeOffset), edx);
+ __ lea(edx, FieldOperand(edx, Code::kHeaderSize));
+ __ mov(FieldOperand(eax, JSFunction::kCodeEntryOffset), edx);
// Return and remove the on-stack parameter.
__ ret(1 * kPointerSize);
=======================================
--- /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc Mon Aug 16
09:06:46 2010
+++ /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc Fri Aug 20
00:10:18 2010
@@ -1298,11 +1298,10 @@
mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
mov(ebx, FieldOperand(edx,
SharedFunctionInfo::kFormalParameterCountOffset));
SmiUntag(ebx);
- mov(edx, FieldOperand(edi, JSFunction::kCodeOffset));
- lea(edx, FieldOperand(edx, Code::kHeaderSize));
ParameterCount expected(ebx);
- InvokeCode(Operand(edx), expected, actual, flag);
+ InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset),
+ expected, actual, flag);
}
@@ -1313,7 +1312,6 @@
// Get the function and setup the context.
mov(edi, Immediate(Handle<JSFunction>(function)));
mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
-
// Invoke the cached code.
Handle<Code> code(function->code());
ParameterCount expected(function->shared()->formal_parameter_count());
@@ -1329,33 +1327,26 @@
// arguments match the expected number of arguments. Fake a
// parameter count to avoid emitting code to do the check.
ParameterCount expected(0);
- GetBuiltinEntry(edx, id);
- InvokeCode(Operand(edx), expected, expected, flag);
+ GetBuiltinFunction(edi, id);
+ InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset),
+ expected, expected, flag);
}
-
-void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript
id) {
- ASSERT(!target.is(edi));
-
- // Load the builtins object into target register.
+void MacroAssembler::GetBuiltinFunction(Register target,
+ Builtins::JavaScript id) {
+ // Load the JavaScript builtin function from the builtins object.
mov(target, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
mov(target, FieldOperand(target, GlobalObject::kBuiltinsOffset));
-
+ mov(target, FieldOperand(target,
+ JSBuiltinsObject::OffsetOfFunctionWithId(id)));
+}
+
+void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript
id) {
+ ASSERT(!target.is(edi));
// Load the JavaScript builtin function from the builtins object.
- mov(edi, FieldOperand(target,
JSBuiltinsObject::OffsetOfFunctionWithId(id)));
-
- // Load the code entry point from the builtins object.
- mov(target, FieldOperand(target,
JSBuiltinsObject::OffsetOfCodeWithId(id)));
- if (FLAG_debug_code) {
- // Make sure the code objects in the builtins object and in the
- // builtin function are the same.
- push(target);
- mov(target, FieldOperand(edi, JSFunction::kCodeOffset));
- cmp(target, Operand(esp, 0));
- Assert(equal, "Builtin code object changed");
- pop(target);
- }
- lea(target, FieldOperand(target, Code::kHeaderSize));
+ GetBuiltinFunction(edi, id);
+ // Load the code entry point from the function into the target register.
+ mov(target, FieldOperand(edi, JSFunction::kCodeEntryOffset));
}
=======================================
--- /branches/bleeding_edge/src/ia32/macro-assembler-ia32.h Mon Aug 16
09:06:46 2010
+++ /branches/bleeding_edge/src/ia32/macro-assembler-ia32.h Fri Aug 20
00:10:18 2010
@@ -169,6 +169,9 @@
// the unresolved list if the name does not resolve.
void InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag);
+ // Store the function for the given builtin in the target register.
+ void GetBuiltinFunction(Register target, Builtins::JavaScript id);
+
// Store the code object for the given builtin in the target register.
void GetBuiltinEntry(Register target, Builtins::JavaScript id);
=======================================
--- /branches/bleeding_edge/src/liveedit.cc Fri Aug 13 06:54:28 2010
+++ /branches/bleeding_edge/src/liveedit.cc Fri Aug 20 00:10:18 2010
@@ -750,7 +750,7 @@
class ReferenceCollectorVisitor : public ObjectVisitor {
public:
explicit ReferenceCollectorVisitor(Code* original)
- : original_(original), rvalues_(10), reloc_infos_(10) {
+ : original_(original), rvalues_(10), reloc_infos_(10),
code_entries_(10) {
}
virtual void VisitPointers(Object** start, Object** end) {
@@ -761,7 +761,13 @@
}
}
- void VisitCodeTarget(RelocInfo* rinfo) {
+ virtual void VisitCodeEntry(Address entry) {
+ if (Code::GetObjectFromEntryAddress(entry) == original_) {
+ code_entries_.Add(entry);
+ }
+ }
+
+ virtual void VisitCodeTarget(RelocInfo* rinfo) {
if (RelocInfo::IsCodeTarget(rinfo->rmode()) &&
Code::GetCodeFromTargetAddress(rinfo->target_address()) ==
original_) {
reloc_infos_.Add(*rinfo);
@@ -778,8 +784,13 @@
for (int i = 0; i < rvalues_.length(); i++) {
*(rvalues_[i]) = substitution;
}
+ Address substitution_entry = substitution->instruction_start();
for (int i = 0; i < reloc_infos_.length(); i++) {
-
reloc_infos_[i].set_target_address(substitution->instruction_start());
+ reloc_infos_[i].set_target_address(substitution_entry);
+ }
+ for (int i = 0; i < code_entries_.length(); i++) {
+ Address entry = code_entries_[i];
+ Memory::Address_at(entry) = substitution_entry;
}
}
@@ -787,6 +798,7 @@
Code* original_;
ZoneList<Object**> rvalues_;
ZoneList<RelocInfo> reloc_infos_;
+ ZoneList<Address> code_entries_;
};
=======================================
--- /branches/bleeding_edge/src/mark-compact.cc Tue Aug 17 05:10:27 2010
+++ /branches/bleeding_edge/src/mark-compact.cc Fri Aug 20 00:10:18 2010
@@ -255,10 +255,9 @@
static void EnableCodeFlushing(bool enabled) {
if (enabled) {
- table_.Register(kVisitJSFunction, &VisitJSFunction);
+ table_.Register(kVisitJSFunction, &VisitJSFunctionAndFlushCode);
} else {
- table_.Register(kVisitJSFunction,
-
&JSObjectVisitor::VisitSpecialized<JSFunction::kSize>);
+ table_.Register(kVisitJSFunction, &VisitJSFunction);
}
}
@@ -299,7 +298,7 @@
table_.Register(kVisitCode, &VisitCode);
- table_.Register(kVisitJSFunction, &VisitJSFunction);
+ table_.Register(kVisitJSFunction, &VisitJSFunctionAndFlushCode);
table_.Register(kVisitPropertyCell,
&FixedBodyVisitor<StaticMarkingVisitor,
@@ -534,16 +533,42 @@
}
- static void VisitJSFunction(Map* map, HeapObject* object) {
- JSFunction* jsfunction = reinterpret_cast<JSFunction*>(object);
-
+ static void VisitCodeEntry(Address entry_address) {
+ Object* code = Code::GetObjectFromEntryAddress(entry_address);
+ Object* old_code = code;
+ VisitPointer(&code);
+ if (code != old_code) {
+ Memory::Address_at(entry_address) =
+ reinterpret_cast<Code*>(code)->entry();
+ }
+ }
+
+
+ static void VisitJSFunctionAndFlushCode(Map* map, HeapObject* object) {
+ JSFunction* jsfunction = reinterpret_cast<JSFunction*>(object);
// The function must have a valid context and not be a builtin.
if (IsValidNotBuiltinContext(jsfunction->unchecked_context())) {
FlushCodeForFunction(jsfunction);
}
-
- JSObjectVisitor::VisitSpecialized<JSFunction::kSize>(map, object);
- }
+ VisitJSFunction(map, object);
+ }
+
+
+ static void VisitJSFunction(Map* map, HeapObject* object) {
+#define SLOT_ADDR(obj, offset) \
+ reinterpret_cast<Object**>((obj)->address() + offset)
+
+ VisitPointers(SLOT_ADDR(object, JSFunction::kPropertiesOffset),
+ SLOT_ADDR(object, JSFunction::kCodeEntryOffset));
+
+ VisitCodeEntry(object->address() + JSFunction::kCodeEntryOffset);
+
+ VisitPointers(SLOT_ADDR(object,
+ JSFunction::kCodeEntryOffset + kPointerSize),
+ SLOT_ADDR(object, JSFunction::kSize));
+#undef SLOT_ADDR
+ }
+
typedef void (*Callback)(Map* map, HeapObject* object);
=======================================
--- /branches/bleeding_edge/src/objects-inl.h Wed Aug 18 06:00:38 2010
+++ /branches/bleeding_edge/src/objects-inl.h Fri Aug 20 00:10:18 2010
@@ -35,9 +35,10 @@
#ifndef V8_OBJECTS_INL_H_
#define V8_OBJECTS_INL_H_
-#include "objects.h"
+#include "memory.h"
#include "contexts.h"
#include "conversions-inl.h"
+#include "objects.h"
#include "property.h"
namespace v8 {
@@ -2408,6 +2409,12 @@
Code* result = reinterpret_cast<Code*>(code);
return result;
}
+
+
+Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
+ return HeapObject::
+ FromAddress(Memory::Address_at(location_of_address) -
Code::kHeaderSize);
+}
Object* Map::prototype() {
@@ -2739,19 +2746,21 @@
Code* JSFunction::code() {
- return Code::cast(READ_FIELD(this, kCodeOffset));
+ return Code::cast(unchecked_code());
}
Code* JSFunction::unchecked_code() {
- return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
+ return reinterpret_cast<Code*>(
+ Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
}
void JSFunction::set_code(Code* value) {
// Skip the write barrier because code is never in new space.
ASSERT(!Heap::InNewSpace(value));
- WRITE_FIELD(this, kCodeOffset, value);
+ Address entry = value->entry();
+ WRITE_INTPTR_FIELD(this, kCodeEntryOffset,
reinterpret_cast<intptr_t>(entry));
}
=======================================
--- /branches/bleeding_edge/src/objects.cc Thu Aug 19 06:28:28 2010
+++ /branches/bleeding_edge/src/objects.cc Fri Aug 20 00:10:18 2010
@@ -1066,12 +1066,15 @@
case JS_VALUE_TYPE:
case JS_ARRAY_TYPE:
case JS_REGEXP_TYPE:
- case JS_FUNCTION_TYPE:
case JS_GLOBAL_PROXY_TYPE:
case JS_GLOBAL_OBJECT_TYPE:
case JS_BUILTINS_OBJECT_TYPE:
JSObject::BodyDescriptor::IterateBody(this, object_size, v);
break;
+ case JS_FUNCTION_TYPE:
+ reinterpret_cast<JSFunction*>(this)
+ ->JSFunctionIterateBody(object_size, v);
+ break;
case ODDBALL_TYPE:
Oddball::BodyDescriptor::IterateBody(this, v);
break;
@@ -4986,6 +4989,15 @@
}
}
}
+
+
+void JSFunction::JSFunctionIterateBody(int object_size, ObjectVisitor* v) {
+ // Iterate over all fields in the body but take care in dealing with
+ // the code entry.
+ IteratePointers(v, kPropertiesOffset, kCodeEntryOffset);
+ v->VisitCodeEntry(this->address() + kCodeEntryOffset);
+ IteratePointers(v, kCodeEntryOffset + kPointerSize, object_size);
+}
Object* JSFunction::SetInstancePrototype(Object* value) {
@@ -5002,7 +5014,6 @@
Heap::ClearInstanceofCache();
return value;
}
-
Object* JSFunction::SetPrototype(Object* value) {
@@ -5230,6 +5241,16 @@
VisitPointer(&target);
CHECK_EQ(target, old_target); // VisitPointer doesn't change Code*
*target.
}
+
+
+void ObjectVisitor::VisitCodeEntry(Address entry_address) {
+ Object* code = Code::GetObjectFromEntryAddress(entry_address);
+ Object* old_code = code;
+ VisitPointer(&code);
+ if (code != old_code) {
+ Memory::Address_at(entry_address) =
reinterpret_cast<Code*>(code)->entry();
+ }
+}
void ObjectVisitor::VisitDebugTarget(RelocInfo* rinfo) {
=======================================
--- /branches/bleeding_edge/src/objects.h Thu Aug 19 06:28:28 2010
+++ /branches/bleeding_edge/src/objects.h Fri Aug 20 00:10:18 2010
@@ -2883,6 +2883,9 @@
// Convert a target address into a code object.
static inline Code* GetCodeFromTargetAddress(Address address);
+ // Convert an entry address into an object.
+ static inline Object* GetObjectFromEntryAddress(Address
location_of_address);
+
// Returns the address of the first instruction.
inline byte* instruction_start();
@@ -3705,6 +3708,10 @@
// Casting.
static inline JSFunction* cast(Object* obj);
+ // Iterates the objects, including code objects indirectly referenced
+ // through pointers to the first instruction in the code object.
+ void JSFunctionIterateBody(int object_size, ObjectVisitor* v);
+
// Dispatched behavior.
#ifdef DEBUG
void JSFunctionPrint();
@@ -3718,9 +3725,9 @@
static Context* GlobalContextFromLiterals(FixedArray* literals);
// Layout descriptors.
- static const int kCodeOffset = JSObject::kHeaderSize;
+ static const int kCodeEntryOffset = JSObject::kHeaderSize;
static const int kPrototypeOrInitialMapOffset =
- kCodeOffset + kPointerSize;
+ kCodeEntryOffset + kPointerSize;
static const int kSharedFunctionInfoOffset =
kPrototypeOrInitialMapOffset + kPointerSize;
static const int kContextOffset = kSharedFunctionInfoOffset +
kPointerSize;
@@ -5435,6 +5442,9 @@
// Visits a code target in the instruction stream.
virtual void VisitCodeTarget(RelocInfo* rinfo);
+ // Visits a code entry in a JS function.
+ virtual void VisitCodeEntry(Address entry_address);
+
// Visits a runtime entry in the instruction stream.
virtual void VisitRuntimeEntry(RelocInfo* rinfo) {}
=======================================
--- /branches/bleeding_edge/src/serialize.cc Wed Aug 11 07:30:14 2010
+++ /branches/bleeding_edge/src/serialize.cc Fri Aug 20 00:10:18 2010
@@ -831,6 +831,12 @@
CASE_STATEMENT(where, how, within,
kLargeFixedArray) \
CASE_BODY(where, how, within, kAnyOldSpace, kUnknownOffsetFromStart)
+#define ONE_PER_CODE_SPACE(where, how,
within) \
+ CASE_STATEMENT(where, how, within,
CODE_SPACE) \
+ CASE_BODY(where, how, within, CODE_SPACE,
kUnknownOffsetFromStart) \
+ CASE_STATEMENT(where, how, within,
kLargeCode) \
+ CASE_BODY(where, how, within, LO_SPACE, kUnknownOffsetFromStart)
+
#define
EMIT_COMMON_REFERENCE_PATTERNS(pseudo_space_number, \
space_number, \
offset_from_start) \
@@ -862,6 +868,8 @@
// Deserialize a new object and write a pointer to it to the current
// object.
ONE_PER_SPACE(kNewObject, kPlain, kStartOfObject)
+ // Support for direct instruction pointers in functions
+ ONE_PER_CODE_SPACE(kNewObject, kPlain, kFirstInstruction)
// Deserialize a new code object and write a pointer to its first
// instruction to the current code object.
ONE_PER_SPACE(kNewObject, kFromCode, kFirstInstruction)
@@ -870,11 +878,14 @@
ALL_SPACES(kBackref, kPlain, kStartOfObject)
// Find a recently deserialized code object using its offset from the
// current allocation point and write a pointer to its first
instruction
- // to the current code object.
+ // to the current code object or the instruction pointer in a
function
+ // object.
ALL_SPACES(kBackref, kFromCode, kFirstInstruction)
+ ALL_SPACES(kBackref, kPlain, kFirstInstruction)
// Find an already deserialized object using its offset from the
start
// and write a pointer to it to the current object.
ALL_SPACES(kFromStart, kPlain, kStartOfObject)
+ ALL_SPACES(kFromStart, kPlain, kFirstInstruction)
// Find an already deserialized code object using its offset from the
// start and write a pointer to its first instruction to the current
code
// object.
@@ -893,6 +904,14 @@
kPlain,
kStartOfObject,
0,
+ kUnknownOffsetFromStart)
+ // Find an code entry in the partial snapshots cache and
+ // write a pointer to it to the current object.
+ CASE_STATEMENT(kPartialSnapshotCache, kPlain, kFirstInstruction, 0)
+ CASE_BODY(kPartialSnapshotCache,
+ kPlain,
+ kFirstInstruction,
+ 0,
kUnknownOffsetFromStart)
// Find an external reference and write a pointer to it to the
current
// object.
@@ -1334,6 +1353,14 @@
serializer_->SerializeObject(target, kFromCode, kFirstInstruction);
bytes_processed_so_far_ += rinfo->target_address_size();
}
+
+
+void Serializer::ObjectSerializer::VisitCodeEntry(Address entry_address) {
+ Code* target =
Code::cast(Code::GetObjectFromEntryAddress(entry_address));
+ OutputRawData(entry_address);
+ serializer_->SerializeObject(target, kPlain, kFirstInstruction);
+ bytes_processed_so_far_ += kPointerSize;
+}
void Serializer::ObjectSerializer::VisitExternalAsciiString(
=======================================
--- /branches/bleeding_edge/src/serialize.h Mon Aug 16 09:06:46 2010
+++ /branches/bleeding_edge/src/serialize.h Fri Aug 20 00:10:18 2010
@@ -448,6 +448,7 @@
void VisitPointers(Object** start, Object** end);
void VisitExternalReferences(Address* start, Address* end);
void VisitCodeTarget(RelocInfo* target);
+ void VisitCodeEntry(Address entry_address);
void VisitRuntimeEntry(RelocInfo* reloc);
// Used for seralizing the external strings that hold the natives
source.
void VisitExternalAsciiString(
=======================================
--- /branches/bleeding_edge/src/x64/builtins-x64.cc Wed Aug 11 06:48:58 2010
+++ /branches/bleeding_edge/src/x64/builtins-x64.cc Fri Aug 20 00:10:18 2010
@@ -310,8 +310,7 @@
__ movsxlq(rbx,
FieldOperand(rdx,
SharedFunctionInfo::kFormalParameterCountOffset));
- __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeOffset));
- __ lea(rdx, FieldOperand(rdx, Code::kHeaderSize));
+ __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
__ cmpq(rax, rbx);
__ j(not_equal,
Handle<Code>(builtin(ArgumentsAdaptorTrampoline)),
=======================================
--- /branches/bleeding_edge/src/x64/codegen-x64.cc Mon Aug 16 09:06:46 2010
+++ /branches/bleeding_edge/src/x64/codegen-x64.cc Fri Aug 20 00:10:18 2010
@@ -2616,8 +2616,10 @@
__ j(is_smi, &build_args);
__ CmpObjectType(rax, JS_FUNCTION_TYPE, rcx);
__ j(not_equal, &build_args);
+ __ movq(rcx, FieldOperand(rax, JSFunction::kCodeEntryOffset));
+ __ subq(rcx, Immediate(Code::kHeaderSize - kHeapObjectTag));
Handle<Code> apply_code(Builtins::builtin(Builtins::FunctionApply));
- __ Cmp(FieldOperand(rax, JSFunction::kCodeOffset), apply_code);
+ __ Cmp(FieldOperand(rcx, SharedFunctionInfo::kCodeOffset),
apply_code);
__ j(not_equal, &build_args);
// Check that applicand is a function.
@@ -8758,7 +8760,8 @@
// Initialize the code pointer in the function to be the one
// found in the shared function info object.
__ movq(rdx, FieldOperand(rdx, SharedFunctionInfo::kCodeOffset));
- __ movq(FieldOperand(rax, JSFunction::kCodeOffset), rdx);
+ __ lea(rdx, FieldOperand(rdx, Code::kHeaderSize));
+ __ movq(FieldOperand(rax, JSFunction::kCodeEntryOffset), rdx);
// Return and remove the on-stack parameter.
=======================================
--- /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Mon Aug 16
09:06:46 2010
+++ /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Fri Aug 20
00:10:18 2010
@@ -581,28 +581,21 @@
}
-void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript
id) {
- ASSERT(!target.is(rdi));
-
+void MacroAssembler::GetBuiltinFunction(Register target,
+ Builtins::JavaScript id) {
// Load the builtins object into target register.
movq(target, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
movq(target, FieldOperand(target, GlobalObject::kBuiltinsOffset));
-
- // Load the JavaScript builtin function from the builtins object.
- movq(rdi, FieldOperand(target,
JSBuiltinsObject::OffsetOfFunctionWithId(id)));
-
- // Load the code entry point from the builtins object.
- movq(target, FieldOperand(target,
JSBuiltinsObject::OffsetOfCodeWithId(id)));
- if (FLAG_debug_code) {
- // Make sure the code objects in the builtins object and in the
- // builtin function are the same.
- push(target);
- movq(target, FieldOperand(rdi, JSFunction::kCodeOffset));
- cmpq(target, Operand(rsp, 0));
- Assert(equal, "Builtin code object changed");
- pop(target);
- }
- lea(target, FieldOperand(target, Code::kHeaderSize));
+ movq(target, FieldOperand(target,
+ JSBuiltinsObject::OffsetOfFunctionWithId(id)));
+}
+
+
+void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript
id) {
+ ASSERT(!target.is(rdi));
+ // Load the JavaScript builtin function from the builtins object.
+ GetBuiltinFunction(rdi, id);
+ movq(target, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
}
@@ -2311,10 +2304,9 @@
movq(rsi, FieldOperand(function, JSFunction::kContextOffset));
movsxlq(rbx,
FieldOperand(rdx,
SharedFunctionInfo::kFormalParameterCountOffset));
- movq(rdx, FieldOperand(rdi, JSFunction::kCodeOffset));
// Advances rdx to the end of the Code object header, to the start of
// the executable code.
- lea(rdx, FieldOperand(rdx, Code::kHeaderSize));
+ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
ParameterCount expected(rbx);
InvokeCode(rdx, expected, actual, flag);
=======================================
--- /branches/bleeding_edge/src/x64/macro-assembler-x64.h Mon Aug 16
09:06:46 2010
+++ /branches/bleeding_edge/src/x64/macro-assembler-x64.h Fri Aug 20
00:10:18 2010
@@ -203,6 +203,9 @@
// the unresolved list if the name does not resolve.
void InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag);
+ // Store the function for the given builtin in the target register.
+ void GetBuiltinFunction(Register target, Builtins::JavaScript id);
+
// Store the code object for the given builtin in the target register.
void GetBuiltinEntry(Register target, Builtins::JavaScript id);
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev