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.
- ldr(r1, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
- ldr(r1, FieldMemOperand(r1, GlobalObject::kBuiltinsOffset));
- int builtins_offset =
- JSBuiltinsObject::kJSBuiltinsOffset + (id * kPointerSize);
- ldr(r1, FieldMemOperand(r1, builtins_offset));
- // Load the code entry point from the function into the target register.
- ldr(target, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
- ldr(target, FieldMemOperand(target, SharedFunctionInfo::kCodeOffset));
+ ldr(r1, FieldMemOperand(target,
+ JSBuiltinsObject::OffsetOfFunctionWithId(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::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));
}
Handle<SharedFunctionInfo> shared
= Handle<SharedFunctionInfo>(function->shared());
if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) return false;
+ builtins->set_javascript_builtin_code(id, shared->code());
}
return true;
}
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.
- mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
- mov(edi, FieldOperand(edi, GlobalObject::kBuiltinsOffset));
- int builtins_offset =
- JSBuiltinsObject::kJSBuiltinsOffset + (id * kPointerSize);
- mov(edi, FieldOperand(edi, builtins_offset));
- // Load the code entry point from the function into the target register.
- mov(target, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
- mov(target, FieldOperand(target, SharedFunctionInfo::kCodeOffset));
- add(Operand(target), Immediate(Code::kHeaderSize - kHeapObjectTag));
+ 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::kSharedFunctionInfoOffset));
+ mov(target, FieldOperand(target, SharedFunctionInfo::kCodeOffset));
+ cmp(target, Operand(esp, 0));
+ Assert(equal, "Builtin code object changed");
+ pop(target);
+ }
+ lea(target, FieldOperand(target, Code::kHeaderSize));
}
Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
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,
Object* value) {
ASSERT(0 <= id && id < kJSBuiltinsCount);
- WRITE_FIELD(this, kJSBuiltinsOffset + (id * kPointerSize), value);
- WRITE_BARRIER(this, kJSBuiltinsOffset + (id * kPointerSize));
+ WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
+ 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));
}
inline Object* javascript_builtin(Builtins::JavaScript id);
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.
static inline JSBuiltinsObject* cast(Object* obj);
#endif
// 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 kJSBuiltinsOffset = GlobalObject::kHeaderSize;
+ static const int kJSBuiltinsCodeOffset =
+ GlobalObject::kHeaderSize + (kJSBuiltinsCount * kPointerSize);
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:
DISALLOW_IMPLICIT_CONSTRUCTORS(JSBuiltinsObject);
};
// unique ID, and deserializing several partial snapshots containing script
// would cause dupes.
ASSERT(!o->IsScript());
- return o->IsString() || o->IsSharedFunctionInfo() || o->IsHeapNumber();
+ return o->IsString() || o->IsSharedFunctionInfo() ||
+ o->IsHeapNumber() || o->IsCode();
}
private:
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.
- movq(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
- movq(rdi, FieldOperand(rdi, GlobalObject::kBuiltinsOffset));
- int builtins_offset =
- JSBuiltinsObject::kJSBuiltinsOffset + (id * kPointerSize);
- movq(rdi, FieldOperand(rdi, builtins_offset));
- // Load the code entry point from the function into the target register.
- movq(target, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
- movq(target, FieldOperand(target, SharedFunctionInfo::kCodeOffset));
- addq(target, Immediate(Code::kHeaderSize - kHeapObjectTag));
+ 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::kSharedFunctionInfoOffset));
+ movq(target, FieldOperand(target, SharedFunctionInfo::kCodeOffset));
+ cmpq(target, Operand(rsp, 0));
+ Assert(equal, "Builtin code object changed");
+ pop(target);
+ }
+ lea(target, FieldOperand(target, Code::kHeaderSize));
}