Commit 1d8ec1e4 authored by vitalyr@chromium.org's avatar vitalyr@chromium.org

One less dependent load in InvokeBuiltin.

Review URL: http://codereview.chromium.org/1638006

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4423 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent c007fd4d
...@@ -1309,15 +1309,29 @@ void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, ...@@ -1309,15 +1309,29 @@ void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) { void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
ASSERT(!target.is(r1));
// 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. // Load the JavaScript builtin function from the builtins object.
ldr(r1, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); ldr(r1, FieldMemOperand(target,
ldr(r1, FieldMemOperand(r1, GlobalObject::kBuiltinsOffset)); JSBuiltinsObject::OffsetOfFunctionWithId(id)));
int builtins_offset =
JSBuiltinsObject::kJSBuiltinsOffset + (id * kPointerSize); // Load the code entry point from the builtins object.
ldr(r1, FieldMemOperand(r1, builtins_offset)); ldr(target, FieldMemOperand(target,
// Load the code entry point from the function into the target register. JSBuiltinsObject::OffsetOfCodeWithId(id)));
ldr(target, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); if (FLAG_debug_code) {
ldr(target, FieldMemOperand(target, SharedFunctionInfo::kCodeOffset)); // Make sure the code objects in the builtins object and in the
// builtin function are the same.
push(r1);
ldr(r1, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
ldr(r1, FieldMemOperand(r1, SharedFunctionInfo::kCodeOffset));
cmp(r1, target);
Assert(eq, "Builtin code object changed");
pop(r1);
}
add(target, target, Operand(Code::kHeaderSize - kHeapObjectTag)); add(target, target, Operand(Code::kHeaderSize - kHeapObjectTag));
} }
......
...@@ -1492,6 +1492,7 @@ bool Genesis::InstallJSBuiltins(Handle<JSBuiltinsObject> builtins) { ...@@ -1492,6 +1492,7 @@ bool Genesis::InstallJSBuiltins(Handle<JSBuiltinsObject> builtins) {
Handle<SharedFunctionInfo> shared Handle<SharedFunctionInfo> shared
= Handle<SharedFunctionInfo>(function->shared()); = Handle<SharedFunctionInfo>(function->shared());
if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) return false; if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) return false;
builtins->set_javascript_builtin_code(id, shared->code());
} }
return true; return true;
} }
......
...@@ -1396,16 +1396,28 @@ void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag) { ...@@ -1396,16 +1396,28 @@ void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag) {
void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) { void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
ASSERT(!target.is(edi));
// Load the builtins object into target register.
mov(target, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
mov(target, FieldOperand(target, GlobalObject::kBuiltinsOffset));
// Load the JavaScript builtin function from the builtins object. // Load the JavaScript builtin function from the builtins object.
mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX))); mov(edi, FieldOperand(target, JSBuiltinsObject::OffsetOfFunctionWithId(id)));
mov(edi, FieldOperand(edi, GlobalObject::kBuiltinsOffset));
int builtins_offset = // Load the code entry point from the builtins object.
JSBuiltinsObject::kJSBuiltinsOffset + (id * kPointerSize); mov(target, FieldOperand(target, JSBuiltinsObject::OffsetOfCodeWithId(id)));
mov(edi, FieldOperand(edi, builtins_offset)); if (FLAG_debug_code) {
// Load the code entry point from the function into the target register. // Make sure the code objects in the builtins object and in the
// builtin function are the same.
push(target);
mov(target, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); mov(target, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
mov(target, FieldOperand(target, SharedFunctionInfo::kCodeOffset)); mov(target, FieldOperand(target, SharedFunctionInfo::kCodeOffset));
add(Operand(target), Immediate(Code::kHeaderSize - kHeapObjectTag)); cmp(target, Operand(esp, 0));
Assert(equal, "Builtin code object changed");
pop(target);
}
lea(target, FieldOperand(target, Code::kHeaderSize));
} }
......
...@@ -2587,15 +2587,29 @@ int JSFunction::NumberOfLiterals() { ...@@ -2587,15 +2587,29 @@ int JSFunction::NumberOfLiterals() {
Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) { Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
ASSERT(0 <= id && id < kJSBuiltinsCount); ASSERT(0 <= id && id < kJSBuiltinsCount);
return READ_FIELD(this, kJSBuiltinsOffset + (id * kPointerSize)); return READ_FIELD(this, OffsetOfFunctionWithId(id));
} }
void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id, void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
Object* value) { Object* value) {
ASSERT(0 <= id && id < kJSBuiltinsCount); ASSERT(0 <= id && id < kJSBuiltinsCount);
WRITE_FIELD(this, kJSBuiltinsOffset + (id * kPointerSize), value); WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
WRITE_BARRIER(this, kJSBuiltinsOffset + (id * kPointerSize)); WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
}
Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
ASSERT(0 <= id && id < kJSBuiltinsCount);
return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
}
void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
Code* value) {
ASSERT(0 <= id && id < kJSBuiltinsCount);
WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
ASSERT(!Heap::InNewSpace(value));
} }
......
...@@ -3543,6 +3543,10 @@ class JSBuiltinsObject: public GlobalObject { ...@@ -3543,6 +3543,10 @@ class JSBuiltinsObject: public GlobalObject {
inline Object* javascript_builtin(Builtins::JavaScript id); inline Object* javascript_builtin(Builtins::JavaScript id);
inline void set_javascript_builtin(Builtins::JavaScript id, Object* value); inline void set_javascript_builtin(Builtins::JavaScript id, Object* value);
// Accessors for code of the runtime routines written in JavaScript.
inline Code* javascript_builtin_code(Builtins::JavaScript id);
inline void set_javascript_builtin_code(Builtins::JavaScript id, Code* value);
// Casting. // Casting.
static inline JSBuiltinsObject* cast(Object* obj); static inline JSBuiltinsObject* cast(Object* obj);
...@@ -3553,11 +3557,23 @@ class JSBuiltinsObject: public GlobalObject { ...@@ -3553,11 +3557,23 @@ class JSBuiltinsObject: public GlobalObject {
#endif #endif
// Layout description. The size of the builtins object includes // Layout description. The size of the builtins object includes
// room for one pointer per runtime routine written in javascript. // room for two pointers per runtime routine written in javascript
// (function and code object).
static const int kJSBuiltinsCount = Builtins::id_count; static const int kJSBuiltinsCount = Builtins::id_count;
static const int kJSBuiltinsOffset = GlobalObject::kHeaderSize; static const int kJSBuiltinsOffset = GlobalObject::kHeaderSize;
static const int kJSBuiltinsCodeOffset =
GlobalObject::kHeaderSize + (kJSBuiltinsCount * kPointerSize);
static const int kSize = static const int kSize =
kJSBuiltinsOffset + (kJSBuiltinsCount * kPointerSize); kJSBuiltinsCodeOffset + (kJSBuiltinsCount * kPointerSize);
static int OffsetOfFunctionWithId(Builtins::JavaScript id) {
return kJSBuiltinsOffset + id * kPointerSize;
}
static int OffsetOfCodeWithId(Builtins::JavaScript id) {
return kJSBuiltinsCodeOffset + id * kPointerSize;
}
private: private:
DISALLOW_IMPLICIT_CONSTRUCTORS(JSBuiltinsObject); DISALLOW_IMPLICIT_CONSTRUCTORS(JSBuiltinsObject);
}; };
......
...@@ -503,7 +503,8 @@ class PartialSerializer : public Serializer { ...@@ -503,7 +503,8 @@ class PartialSerializer : public Serializer {
// unique ID, and deserializing several partial snapshots containing script // unique ID, and deserializing several partial snapshots containing script
// would cause dupes. // would cause dupes.
ASSERT(!o->IsScript()); ASSERT(!o->IsScript());
return o->IsString() || o->IsSharedFunctionInfo() || o->IsHeapNumber(); return o->IsString() || o->IsSharedFunctionInfo() ||
o->IsHeapNumber() || o->IsCode();
} }
private: private:
......
...@@ -445,16 +445,28 @@ void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag) { ...@@ -445,16 +445,28 @@ void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag) {
void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) { void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
ASSERT(!target.is(rdi));
// 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. // Load the JavaScript builtin function from the builtins object.
movq(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX))); movq(rdi, FieldOperand(target, JSBuiltinsObject::OffsetOfFunctionWithId(id)));
movq(rdi, FieldOperand(rdi, GlobalObject::kBuiltinsOffset));
int builtins_offset = // Load the code entry point from the builtins object.
JSBuiltinsObject::kJSBuiltinsOffset + (id * kPointerSize); movq(target, FieldOperand(target, JSBuiltinsObject::OffsetOfCodeWithId(id)));
movq(rdi, FieldOperand(rdi, builtins_offset)); if (FLAG_debug_code) {
// Load the code entry point from the function into the target register. // Make sure the code objects in the builtins object and in the
// builtin function are the same.
push(target);
movq(target, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); movq(target, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
movq(target, FieldOperand(target, SharedFunctionInfo::kCodeOffset)); movq(target, FieldOperand(target, SharedFunctionInfo::kCodeOffset));
addq(target, Immediate(Code::kHeaderSize - kHeapObjectTag)); cmpq(target, Operand(rsp, 0));
Assert(equal, "Builtin code object changed");
pop(target);
}
lea(target, FieldOperand(target, Code::kHeaderSize));
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment