| 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 23 matching lines...) Expand all Loading... |
| 34 #include "serialize.h" | 34 #include "serialize.h" |
| 35 | 35 |
| 36 namespace v8 { | 36 namespace v8 { |
| 37 namespace internal { | 37 namespace internal { |
| 38 | 38 |
| 39 // ------------------------------------------------------------------------- | 39 // ------------------------------------------------------------------------- |
| 40 // MacroAssembler implementation. | 40 // MacroAssembler implementation. |
| 41 | 41 |
| 42 MacroAssembler::MacroAssembler(void* buffer, int size) | 42 MacroAssembler::MacroAssembler(void* buffer, int size) |
| 43 : Assembler(buffer, size), | 43 : Assembler(buffer, size), |
| 44 unresolved_(0), | |
| 45 generating_stub_(false), | 44 generating_stub_(false), |
| 46 allow_stub_calls_(true), | 45 allow_stub_calls_(true), |
| 47 code_object_(Heap::undefined_value()) { | 46 code_object_(Heap::undefined_value()) { |
| 48 } | 47 } |
| 49 | 48 |
| 50 | 49 |
| 51 static void RecordWriteHelper(MacroAssembler* masm, | 50 static void RecordWriteHelper(MacroAssembler* masm, |
| 52 Register object, | 51 Register object, |
| 53 Register addr, | 52 Register addr, |
| 54 Register scratch) { | 53 Register scratch) { |
| (...skipping 1297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1352 mov(ebx, FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset)); | 1351 mov(ebx, FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset)); |
| 1353 mov(edx, FieldOperand(edx, SharedFunctionInfo::kCodeOffset)); | 1352 mov(edx, FieldOperand(edx, SharedFunctionInfo::kCodeOffset)); |
| 1354 lea(edx, FieldOperand(edx, Code::kHeaderSize)); | 1353 lea(edx, FieldOperand(edx, Code::kHeaderSize)); |
| 1355 | 1354 |
| 1356 ParameterCount expected(ebx); | 1355 ParameterCount expected(ebx); |
| 1357 InvokeCode(Operand(edx), expected, actual, flag); | 1356 InvokeCode(Operand(edx), expected, actual, flag); |
| 1358 } | 1357 } |
| 1359 | 1358 |
| 1360 | 1359 |
| 1361 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag) { | 1360 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag) { |
| 1362 bool resolved; | |
| 1363 Handle<Code> code = ResolveBuiltin(id, &resolved); | |
| 1364 | |
| 1365 // Calls are not allowed in some stubs. | 1361 // Calls are not allowed in some stubs. |
| 1366 ASSERT(flag == JUMP_FUNCTION || allow_stub_calls()); | 1362 ASSERT(flag == JUMP_FUNCTION || allow_stub_calls()); |
| 1367 | 1363 |
| 1368 // Rely on the assertion to check that the number of provided | 1364 // Rely on the assertion to check that the number of provided |
| 1369 // arguments match the expected number of arguments. Fake a | 1365 // arguments match the expected number of arguments. Fake a |
| 1370 // parameter count to avoid emitting code to do the check. | 1366 // parameter count to avoid emitting code to do the check. |
| 1371 ParameterCount expected(0); | 1367 ParameterCount expected(0); |
| 1372 InvokeCode(Handle<Code>(code), expected, expected, | 1368 GetBuiltinEntry(edx, id); |
| 1373 RelocInfo::CODE_TARGET, flag); | 1369 InvokeCode(Operand(edx), expected, expected, flag); |
| 1374 | |
| 1375 const char* name = Builtins::GetName(id); | |
| 1376 int argc = Builtins::GetArgumentsCount(id); | |
| 1377 | |
| 1378 if (!resolved) { | |
| 1379 uint32_t flags = | |
| 1380 Bootstrapper::FixupFlagsArgumentsCount::encode(argc) | | |
| 1381 Bootstrapper::FixupFlagsUseCodeObject::encode(false); | |
| 1382 Unresolved entry = { pc_offset() - sizeof(int32_t), flags, name }; | |
| 1383 unresolved_.Add(entry); | |
| 1384 } | |
| 1385 } | 1370 } |
| 1386 | 1371 |
| 1387 | 1372 |
| 1388 void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) { | 1373 void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) { |
| 1389 bool resolved; | 1374 // Load the JavaScript builtin function from the builtins object |
| 1390 Handle<Code> code = ResolveBuiltin(id, &resolved); | 1375 // using the target register as a scratch register. |
| 1391 | 1376 mov(target, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX))); |
| 1392 const char* name = Builtins::GetName(id); | 1377 mov(target, FieldOperand(target, GlobalObject::kBuiltinsOffset)); |
| 1393 int argc = Builtins::GetArgumentsCount(id); | 1378 int builtins_offset = |
| 1394 | 1379 JSBuiltinsObject::kJSBuiltinsOffset + (id * kPointerSize); |
| 1395 mov(Operand(target), Immediate(code)); | 1380 mov(edi, FieldOperand(target, builtins_offset)); |
| 1396 if (!resolved) { | 1381 // Load the code entry point from the function into the target register. |
| 1397 uint32_t flags = | 1382 mov(target, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
| 1398 Bootstrapper::FixupFlagsArgumentsCount::encode(argc) | | 1383 mov(target, FieldOperand(target, SharedFunctionInfo::kCodeOffset)); |
| 1399 Bootstrapper::FixupFlagsUseCodeObject::encode(true); | |
| 1400 Unresolved entry = { pc_offset() - sizeof(int32_t), flags, name }; | |
| 1401 unresolved_.Add(entry); | |
| 1402 } | |
| 1403 add(Operand(target), Immediate(Code::kHeaderSize - kHeapObjectTag)); | 1384 add(Operand(target), Immediate(Code::kHeaderSize - kHeapObjectTag)); |
| 1404 } | 1385 } |
| 1405 | 1386 |
| 1406 | 1387 |
| 1407 Handle<Code> MacroAssembler::ResolveBuiltin(Builtins::JavaScript id, | |
| 1408 bool* resolved) { | |
| 1409 // Move the builtin function into the temporary function slot by | |
| 1410 // reading it from the builtins object. NOTE: We should be able to | |
| 1411 // reduce this to two instructions by putting the function table in | |
| 1412 // the global object instead of the "builtins" object and by using a | |
| 1413 // real register for the function. | |
| 1414 mov(edx, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX))); | |
| 1415 mov(edx, FieldOperand(edx, GlobalObject::kBuiltinsOffset)); | |
| 1416 int builtins_offset = | |
| 1417 JSBuiltinsObject::kJSBuiltinsOffset + (id * kPointerSize); | |
| 1418 mov(edi, FieldOperand(edx, builtins_offset)); | |
| 1419 | |
| 1420 return Builtins::GetCode(id, resolved); | |
| 1421 } | |
| 1422 | |
| 1423 | |
| 1424 void MacroAssembler::LoadContext(Register dst, int context_chain_length) { | 1388 void MacroAssembler::LoadContext(Register dst, int context_chain_length) { |
| 1425 if (context_chain_length > 0) { | 1389 if (context_chain_length > 0) { |
| 1426 // Move up the chain of contexts to the context containing the slot. | 1390 // Move up the chain of contexts to the context containing the slot. |
| 1427 mov(dst, Operand(esi, Context::SlotOffset(Context::CLOSURE_INDEX))); | 1391 mov(dst, Operand(esi, Context::SlotOffset(Context::CLOSURE_INDEX))); |
| 1428 // Load the function context (which is the incoming, outer context). | 1392 // Load the function context (which is the incoming, outer context). |
| 1429 mov(dst, FieldOperand(dst, JSFunction::kContextOffset)); | 1393 mov(dst, FieldOperand(dst, JSFunction::kContextOffset)); |
| 1430 for (int i = 1; i < context_chain_length; i++) { | 1394 for (int i = 1; i < context_chain_length; i++) { |
| 1431 mov(dst, Operand(dst, Context::SlotOffset(Context::CLOSURE_INDEX))); | 1395 mov(dst, Operand(dst, Context::SlotOffset(Context::CLOSURE_INDEX))); |
| 1432 mov(dst, FieldOperand(dst, JSFunction::kContextOffset)); | 1396 mov(dst, FieldOperand(dst, JSFunction::kContextOffset)); |
| 1433 } | 1397 } |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1607 // Indicate that code has changed. | 1571 // Indicate that code has changed. |
| 1608 CPU::FlushICache(address_, size_); | 1572 CPU::FlushICache(address_, size_); |
| 1609 | 1573 |
| 1610 // Check that the code was patched as expected. | 1574 // Check that the code was patched as expected. |
| 1611 ASSERT(masm_.pc_ == address_ + size_); | 1575 ASSERT(masm_.pc_ == address_ + size_); |
| 1612 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); | 1576 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); |
| 1613 } | 1577 } |
| 1614 | 1578 |
| 1615 | 1579 |
| 1616 } } // namespace v8::internal | 1580 } } // namespace v8::internal |
| OLD | NEW |