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 |