Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(112)

Side by Side Diff: src/x64/assembler-x64.h

Issue 200095: Add near calls (32-bit displacement) to Code objects on X64 platform. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/serialize.cc ('k') | src/x64/assembler-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. 1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
2 // All Rights Reserved. 2 // All Rights Reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // - Redistributions of source code must retain the above copyright notice, 8 // - Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer. 9 // this list of conditions and the following disclaimer.
10 // 10 //
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 // is too small, a fatal error occurs. No deallocation of the buffer is done 433 // is too small, a fatal error occurs. No deallocation of the buffer is done
434 // upon destruction of the assembler. 434 // upon destruction of the assembler.
435 Assembler(void* buffer, int buffer_size); 435 Assembler(void* buffer, int buffer_size);
436 ~Assembler(); 436 ~Assembler();
437 437
438 // GetCode emits any pending (non-emitted) code and fills the descriptor 438 // GetCode emits any pending (non-emitted) code and fills the descriptor
439 // desc. GetCode() is idempotent; it returns the same result if no other 439 // desc. GetCode() is idempotent; it returns the same result if no other
440 // Assembler functions are invoked in between GetCode() calls. 440 // Assembler functions are invoked in between GetCode() calls.
441 void GetCode(CodeDesc* desc); 441 void GetCode(CodeDesc* desc);
442 442
443 // Read/Modify the code target in the branch/call instruction at pc. 443 // Read/Modify the code target in the relative branch/call instruction at pc.
444 // On the x64 architecture, the address is absolute, not relative. 444 // On the x64 architecture, we use relative jumps with a 32-bit displacement
445 // to jump to other Code objects in the Code space in the heap.
446 // Jumps to C functions are done indirectly through a 64-bit register holding
447 // the absolute address of the target.
448 // These functions convert between absolute Addresses of Code objects and
449 // the relative displacements stored in the code.
445 static inline Address target_address_at(Address pc); 450 static inline Address target_address_at(Address pc);
446 static inline void set_target_address_at(Address pc, Address target); 451 static inline void set_target_address_at(Address pc, Address target);
447 452 inline Handle<Object> code_target_object_handle_at(Address pc);
448 // Distance between the address of the code target in the call instruction 453 // Distance between the address of the code target in the call instruction
449 // and the return address. Checked in the debug build. 454 // and the return address pushed on the stack.
450 static const int kCallTargetAddressOffset = 3 + kPointerSize; 455 static const int kCallTargetAddressOffset = 4; // Use 32-bit displacement.
451 // Distance between start of patched return sequence and the emitted address 456 // Distance between the start of the JS return sequence and where the
452 // to jump to (movq = REX.W 0xB8+r.). 457 // 32-bit displacement of a near call would be, relative to the pushed
453 static const int kPatchReturnSequenceAddressOffset = 2; 458 // return address. TODO: Use return sequence length instead.
454 459 // Should equal Debug::kX64JSReturnSequenceLength - kCallTargetAddressOffset;
460 static const int kPatchReturnSequenceAddressOffset = 13 - 4;
461 // TODO(X64): Rename this, removing the "Real", after changing the above.
462 static const int kRealPatchReturnSequenceAddressOffset = 2;
455 // --------------------------------------------------------------------------- 463 // ---------------------------------------------------------------------------
456 // Code generation 464 // Code generation
457 // 465 //
458 // Function names correspond one-to-one to x64 instruction mnemonics. 466 // Function names correspond one-to-one to x64 instruction mnemonics.
459 // Unless specified otherwise, instructions operate on 64-bit operands. 467 // Unless specified otherwise, instructions operate on 64-bit operands.
460 // 468 //
461 // If we need versions of an assembly instruction that operate on different 469 // If we need versions of an assembly instruction that operate on different
462 // width arguments, we add a single-letter suffix specifying the width. 470 // width arguments, we add a single-letter suffix specifying the width.
463 // This is done for the following instructions: mov, cmp, inc, dec, 471 // This is done for the following instructions: mov, cmp, inc, dec,
464 // add, sub, and test. 472 // add, sub, and test.
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after
916 // bind(&L); // illegal: a label may be bound only once 924 // bind(&L); // illegal: a label may be bound only once
917 // 925 //
918 // Note: The same Label can be used for forward and backward branches 926 // Note: The same Label can be used for forward and backward branches
919 // but it may be bound only once. 927 // but it may be bound only once.
920 928
921 void bind(Label* L); // binds an unbound label L to the current code position 929 void bind(Label* L); // binds an unbound label L to the current code position
922 930
923 // Calls 931 // Calls
924 // Call near relative 32-bit displacement, relative to next instruction. 932 // Call near relative 32-bit displacement, relative to next instruction.
925 void call(Label* L); 933 void call(Label* L);
934 void call(Handle<Code> target, RelocInfo::Mode rmode);
926 935
927 // Call near absolute indirect, address in register 936 // Call near absolute indirect, address in register
928 void call(Register adr); 937 void call(Register adr);
929 938
930 // Call near indirect 939 // Call near indirect
931 void call(const Operand& operand); 940 void call(const Operand& operand);
932 941
933 // Jumps 942 // Jumps
934 // Jump short or near relative. 943 // Jump short or near relative.
944 // Use a 32-bit signed displacement.
935 void jmp(Label* L); // unconditional jump to L 945 void jmp(Label* L); // unconditional jump to L
946 void jmp(Handle<Code> target, RelocInfo::Mode rmode);
936 947
937 // Jump near absolute indirect (r64) 948 // Jump near absolute indirect (r64)
938 void jmp(Register adr); 949 void jmp(Register adr);
939 950
940 // Jump near absolute indirect (m64) 951 // Jump near absolute indirect (m64)
941 void jmp(const Operand& src); 952 void jmp(const Operand& src);
942 953
943 // Conditional jumps 954 // Conditional jumps
944 void j(Condition cc, Label* L); 955 void j(Condition cc, Label* L);
956 void j(Condition cc, Handle<Code> target, RelocInfo::Mode rmode);
945 957
946 // Floating-point operations 958 // Floating-point operations
947 void fld(int i); 959 void fld(int i);
948 960
949 void fld1(); 961 void fld1();
950 void fldz(); 962 void fldz();
951 963
952 void fld_s(const Operand& adr); 964 void fld_s(const Operand& adr);
953 void fld_d(const Operand& adr); 965 void fld_d(const Operand& adr);
954 966
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1040 void RecordJSReturn(); 1052 void RecordJSReturn();
1041 1053
1042 // Record a comment relocation entry that can be used by a disassembler. 1054 // Record a comment relocation entry that can be used by a disassembler.
1043 // Use --debug_code to enable. 1055 // Use --debug_code to enable.
1044 void RecordComment(const char* msg); 1056 void RecordComment(const char* msg);
1045 1057
1046 void RecordPosition(int pos); 1058 void RecordPosition(int pos);
1047 void RecordStatementPosition(int pos); 1059 void RecordStatementPosition(int pos);
1048 void WriteRecordedPositions(); 1060 void WriteRecordedPositions();
1049 1061
1050 // Writes a doubleword of data in the code stream.
1051 // Used for inline tables, e.g., jump-tables.
1052 // void dd(uint32_t data);
1053
1054 // Writes a quadword of data in the code stream.
1055 // Used for inline tables, e.g., jump-tables.
1056 // void dd(uint64_t data, RelocInfo::Mode reloc_info);
1057
1058 int pc_offset() const { return pc_ - buffer_; } 1062 int pc_offset() const { return pc_ - buffer_; }
1059 int current_statement_position() const { return current_statement_position_; } 1063 int current_statement_position() const { return current_statement_position_; }
1060 int current_position() const { return current_position_; } 1064 int current_position() const { return current_position_; }
1061 1065
1062 // Check if there is less than kGap bytes available in the buffer. 1066 // Check if there is less than kGap bytes available in the buffer.
1063 // If this is the case, we need to grow the buffer before emitting 1067 // If this is the case, we need to grow the buffer before emitting
1064 // an instruction or relocation information. 1068 // an instruction or relocation information.
1065 inline bool buffer_overflow() const { 1069 inline bool buffer_overflow() const {
1066 return pc_ >= reloc_info_writer.pos() - kGap; 1070 return pc_ >= reloc_info_writer.pos() - kGap;
1067 } 1071 }
(...skipping 21 matching lines...) Expand all
1089 } 1093 }
1090 void long_at_put(int pos, uint32_t x) { 1094 void long_at_put(int pos, uint32_t x) {
1091 *reinterpret_cast<uint32_t*>(addr_at(pos)) = x; 1095 *reinterpret_cast<uint32_t*>(addr_at(pos)) = x;
1092 } 1096 }
1093 1097
1094 // code emission 1098 // code emission
1095 void GrowBuffer(); 1099 void GrowBuffer();
1096 1100
1097 void emit(byte x) { *pc_++ = x; } 1101 void emit(byte x) { *pc_++ = x; }
1098 inline void emitl(uint32_t x); 1102 inline void emitl(uint32_t x);
1099 inline void emit(Handle<Object> handle);
1100 inline void emitq(uint64_t x, RelocInfo::Mode rmode); 1103 inline void emitq(uint64_t x, RelocInfo::Mode rmode);
1101 inline void emitw(uint16_t x); 1104 inline void emitw(uint16_t x);
1105 inline void emit_code_target(Handle<Code> target, RelocInfo::Mode rmode);
1102 void emit(Immediate x) { emitl(x.value_); } 1106 void emit(Immediate x) { emitl(x.value_); }
1103 1107
1104 // Emits a REX prefix that encodes a 64-bit operand size and 1108 // Emits a REX prefix that encodes a 64-bit operand size and
1105 // the top bit of both register codes. 1109 // the top bit of both register codes.
1106 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. 1110 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
1107 // REX.W is set. 1111 // REX.W is set.
1108 inline void emit_rex_64(Register reg, Register rm_reg); 1112 inline void emit_rex_64(Register reg, Register rm_reg);
1109 inline void emit_rex_64(XMMRegister reg, Register rm_reg); 1113 inline void emit_rex_64(XMMRegister reg, Register rm_reg);
1110 1114
1111 // Emits a REX prefix that encodes a 64-bit operand size and 1115 // Emits a REX prefix that encodes a 64-bit operand size and
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
1269 int buffer_size_; 1273 int buffer_size_;
1270 // True if the assembler owns the buffer, false if buffer is external. 1274 // True if the assembler owns the buffer, false if buffer is external.
1271 bool own_buffer_; 1275 bool own_buffer_;
1272 // A previously allocated buffer of kMinimalBufferSize bytes, or NULL. 1276 // A previously allocated buffer of kMinimalBufferSize bytes, or NULL.
1273 static byte* spare_buffer_; 1277 static byte* spare_buffer_;
1274 1278
1275 // code generation 1279 // code generation
1276 byte* pc_; // the program counter; moves forward 1280 byte* pc_; // the program counter; moves forward
1277 RelocInfoWriter reloc_info_writer; 1281 RelocInfoWriter reloc_info_writer;
1278 1282
1283 List< Handle<Code> > code_targets_;
1279 // push-pop elimination 1284 // push-pop elimination
1280 byte* last_pc_; 1285 byte* last_pc_;
1281 1286
1282 // source position information 1287 // source position information
1283 int current_statement_position_; 1288 int current_statement_position_;
1284 int current_position_; 1289 int current_position_;
1285 int written_statement_position_; 1290 int written_statement_position_;
1286 int written_position_; 1291 int written_position_;
1287 }; 1292 };
1288 1293
(...skipping 21 matching lines...) Expand all
1310 private: 1315 private:
1311 Assembler* assembler_; 1316 Assembler* assembler_;
1312 #ifdef DEBUG 1317 #ifdef DEBUG
1313 int space_before_; 1318 int space_before_;
1314 #endif 1319 #endif
1315 }; 1320 };
1316 1321
1317 } } // namespace v8::internal 1322 } } // namespace v8::internal
1318 1323
1319 #endif // V8_X64_ASSEMBLER_X64_H_ 1324 #endif // V8_X64_ASSEMBLER_X64_H_
OLDNEW
« no previous file with comments | « src/serialize.cc ('k') | src/x64/assembler-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698