| Index: src/ia32/macro-assembler-ia32.cc
|
| ===================================================================
|
| --- src/ia32/macro-assembler-ia32.cc (revision 3935)
|
| +++ src/ia32/macro-assembler-ia32.cc (working copy)
|
| @@ -41,7 +41,6 @@
|
|
|
| MacroAssembler::MacroAssembler(void* buffer, int size)
|
| : Assembler(buffer, size),
|
| - unresolved_(0),
|
| generating_stub_(false),
|
| allow_stub_calls_(true),
|
| code_object_(Heap::undefined_value()) {
|
| @@ -308,6 +307,13 @@
|
| }
|
| }
|
| }
|
| +
|
| +void MacroAssembler::DebugBreak() {
|
| + Set(eax, Immediate(0));
|
| + mov(ebx, Immediate(ExternalReference(Runtime::kDebugBreak)));
|
| + CEntryStub ces(1);
|
| + call(ces.GetCode(), RelocInfo::DEBUG_BREAK);
|
| +}
|
| #endif
|
|
|
| void MacroAssembler::Set(Register dst, const Immediate& x) {
|
| @@ -377,6 +383,17 @@
|
| }
|
|
|
|
|
| +void MacroAssembler::AbortIfNotNumber(Register object, const char* msg) {
|
| + Label ok;
|
| + test(object, Immediate(kSmiTagMask));
|
| + j(zero, &ok);
|
| + cmp(FieldOperand(object, HeapObject::kMapOffset),
|
| + Factory::heap_number_map());
|
| + Assert(equal, msg);
|
| + bind(&ok);
|
| +}
|
| +
|
| +
|
| void MacroAssembler::EnterFrame(StackFrame::Type type) {
|
| push(ebp);
|
| mov(ebp, Operand(esp));
|
| @@ -409,12 +426,8 @@
|
|
|
| // Reserve room for entry stack pointer and push the debug marker.
|
| ASSERT(ExitFrameConstants::kSPOffset == -1 * kPointerSize);
|
| - push(Immediate(0)); // saved entry sp, patched before call
|
| - if (mode == ExitFrame::MODE_DEBUG) {
|
| - push(Immediate(0));
|
| - } else {
|
| - push(Immediate(CodeObject()));
|
| - }
|
| + push(Immediate(0)); // Saved entry sp, patched before call.
|
| + push(Immediate(CodeObject())); // Accessed from ExitFrame::code_slot.
|
|
|
| // Save the frame pointer and the context in top.
|
| ExternalReference c_entry_fp_address(Top::k_c_entry_fp_address);
|
| @@ -551,6 +564,7 @@
|
| Register MacroAssembler::CheckMaps(JSObject* object, Register object_reg,
|
| JSObject* holder, Register holder_reg,
|
| Register scratch,
|
| + int save_at_depth,
|
| Label* miss) {
|
| // Make sure there's no overlap between scratch and the other
|
| // registers.
|
| @@ -558,8 +572,12 @@
|
|
|
| // Keep track of the current object in register reg.
|
| Register reg = object_reg;
|
| - int depth = 1;
|
| + int depth = 0;
|
|
|
| + if (save_at_depth == depth) {
|
| + mov(Operand(esp, kPointerSize), object_reg);
|
| + }
|
| +
|
| // Check the maps in the prototype chain.
|
| // Traverse the prototype chain from the object and do map checks.
|
| while (object != holder) {
|
| @@ -590,7 +608,6 @@
|
| // to it in the code. Load it from the map.
|
| reg = holder_reg; // from now the object is in holder_reg
|
| mov(reg, FieldOperand(scratch, Map::kPrototypeOffset));
|
| -
|
| } else {
|
| // Check the map of the current object.
|
| cmp(FieldOperand(reg, HeapObject::kMapOffset),
|
| @@ -608,6 +625,10 @@
|
| mov(reg, Handle<JSObject>(prototype));
|
| }
|
|
|
| + if (save_at_depth == depth) {
|
| + mov(Operand(esp, kPointerSize), reg);
|
| + }
|
| +
|
| // Go to the next object in the prototype chain.
|
| object = prototype;
|
| }
|
| @@ -618,7 +639,7 @@
|
| j(not_equal, miss, not_taken);
|
|
|
| // Log the check depth.
|
| - LOG(IntEvent("check-maps-depth", depth));
|
| + LOG(IntEvent("check-maps-depth", depth + 1));
|
|
|
| // Perform security check for access to the global object and return
|
| // the holder register.
|
| @@ -1135,6 +1156,16 @@
|
| }
|
|
|
|
|
| +void MacroAssembler::CallExternalReference(ExternalReference ref,
|
| + int num_arguments) {
|
| + mov(eax, Immediate(num_arguments));
|
| + mov(ebx, Immediate(ref));
|
| +
|
| + CEntryStub stub(1);
|
| + CallStub(&stub);
|
| +}
|
| +
|
| +
|
| Object* MacroAssembler::TryCallRuntime(Runtime::Function* f,
|
| int num_arguments) {
|
| if (f->nargs >= 0 && f->nargs != num_arguments) {
|
| @@ -1355,10 +1386,22 @@
|
| }
|
|
|
|
|
| +void MacroAssembler::InvokeFunction(JSFunction* function,
|
| + const ParameterCount& actual,
|
| + InvokeFlag flag) {
|
| + ASSERT(function->is_compiled());
|
| + // 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());
|
| + InvokeCode(code, expected, actual, RelocInfo::CODE_TARGET, flag);
|
| +}
|
| +
|
| +
|
| void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag) {
|
| - bool resolved;
|
| - Handle<Code> code = ResolveBuiltin(id, &resolved);
|
| -
|
| // Calls are not allowed in some stubs.
|
| ASSERT(flag == JUMP_FUNCTION || allow_stub_calls());
|
|
|
| @@ -1366,55 +1409,22 @@
|
| // arguments match the expected number of arguments. Fake a
|
| // parameter count to avoid emitting code to do the check.
|
| ParameterCount expected(0);
|
| - InvokeCode(Handle<Code>(code), expected, expected,
|
| - RelocInfo::CODE_TARGET, flag);
|
| -
|
| - const char* name = Builtins::GetName(id);
|
| - int argc = Builtins::GetArgumentsCount(id);
|
| -
|
| - if (!resolved) {
|
| - uint32_t flags =
|
| - Bootstrapper::FixupFlagsArgumentsCount::encode(argc) |
|
| - Bootstrapper::FixupFlagsUseCodeObject::encode(false);
|
| - Unresolved entry = { pc_offset() - sizeof(int32_t), flags, name };
|
| - unresolved_.Add(entry);
|
| - }
|
| + GetBuiltinEntry(edx, id);
|
| + InvokeCode(Operand(edx), expected, expected, flag);
|
| }
|
|
|
|
|
| void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
|
| - bool resolved;
|
| - Handle<Code> code = ResolveBuiltin(id, &resolved);
|
| -
|
| - const char* name = Builtins::GetName(id);
|
| - int argc = Builtins::GetArgumentsCount(id);
|
| -
|
| - mov(Operand(target), Immediate(code));
|
| - if (!resolved) {
|
| - uint32_t flags =
|
| - Bootstrapper::FixupFlagsArgumentsCount::encode(argc) |
|
| - Bootstrapper::FixupFlagsUseCodeObject::encode(true);
|
| - Unresolved entry = { pc_offset() - sizeof(int32_t), flags, name };
|
| - unresolved_.Add(entry);
|
| - }
|
| - add(Operand(target), Immediate(Code::kHeaderSize - kHeapObjectTag));
|
| -}
|
| -
|
| -
|
| -Handle<Code> MacroAssembler::ResolveBuiltin(Builtins::JavaScript id,
|
| - bool* resolved) {
|
| - // Move the builtin function into the temporary function slot by
|
| - // reading it from the builtins object. NOTE: We should be able to
|
| - // reduce this to two instructions by putting the function table in
|
| - // the global object instead of the "builtins" object and by using a
|
| - // real register for the function.
|
| - mov(edx, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
|
| - mov(edx, FieldOperand(edx, 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(edx, builtins_offset));
|
| -
|
| - return Builtins::GetCode(id, resolved);
|
| + 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));
|
| }
|
|
|
|
|
| @@ -1559,6 +1569,20 @@
|
| }
|
|
|
|
|
| +void MacroAssembler::JumpIfInstanceTypeIsNotSequentialAscii(
|
| + Register instance_type,
|
| + Register scratch,
|
| + Label *failure) {
|
| + if (!scratch.is(instance_type)) {
|
| + mov(scratch, instance_type);
|
| + }
|
| + and_(scratch,
|
| + kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask);
|
| + cmp(scratch, kStringTag | kSeqStringTag | kAsciiStringTag);
|
| + j(not_equal, failure);
|
| +}
|
| +
|
| +
|
| void MacroAssembler::JumpIfNotBothSequentialAsciiStrings(Register object1,
|
| Register object2,
|
| Register scratch1,
|
|
|