Skip to content

Commit 78e3f73

Browse files
author
axiongsupra
committed
Save code
1 parent 38b28e7 commit 78e3f73

File tree

3 files changed

+143
-37
lines changed

3 files changed

+143
-37
lines changed

aptos-move/aptos-gas-profiling/src/log.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -268,10 +268,11 @@ impl ExecutionAndIOCosts {
268268
}
269269

270270
if total != self.total {
271-
panic!(
272-
"Execution & IO costs do not add up. Check if the gas meter & the gas profiler have been implemented correctly. From gas meter: {}. Calculated: {}.",
273-
self.total, total
274-
)
271+
// Aosen: This panic is disabled because we are changing the gas meter.
272+
// panic!(
273+
// "Execution & IO costs do not add up. Check if the gas meter & the gas profiler have been implemented correctly. From gas meter: {}. Calculated: {}.",
274+
// self.total, total
275+
// )
275276
}
276277
}
277278
}

aptos-move/aptos-gas-profiling/src/profiler.rs

Lines changed: 134 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright © Aptos Foundation
22
// SPDX-License-Identifier: Apache-2.0
33

4+
use std::collections::HashMap;
45
use crate::log::{
56
CallFrame, Dependency, EventStorage, EventTransient, ExecutionAndIOCosts, ExecutionGasEvent,
67
FrameName, StorageFees, TransactionGasLog, WriteOpType, WriteStorage, WriteTransient,
@@ -41,6 +42,8 @@ pub struct GasProfiler<G> {
4142
events_transient: Vec<EventTransient>,
4243
write_set_transient: Vec<WriteTransient>,
4344
storage_fees: Option<StorageFees>,
45+
module_gas_usage: HashMap<ModuleId, InternalGas>,
46+
gas_cost_stack: Vec<InternalGas>
4447
}
4548

4649
// TODO: consider switching to a library like https://docs.rs/delegate/latest/delegate/.
@@ -98,6 +101,8 @@ impl<G> GasProfiler<G> {
98101
events_transient: vec![],
99102
write_set_transient: vec![],
100103
storage_fees: None,
104+
module_gas_usage: HashMap::new(),
105+
gas_cost_stack: vec![]
101106
}
102107
}
103108

@@ -118,14 +123,129 @@ impl<G> GasProfiler<G> {
118123
events_transient: vec![],
119124
write_set_transient: vec![],
120125
storage_fees: None,
126+
module_gas_usage: HashMap::new(),
127+
gas_cost_stack: vec![]
121128
}
122129
}
123130
}
124131

132+
// 0 -> 800 -> 1500 -> 2000 -> 2500
133+
// A::Foo() { Bar()}
134+
// B::Bar() { Barz()}
135+
// C::Barz() {}
136+
// TODO: add a new value if it is intermodule call, also think about return intermodule. call to 0x1 should be ignored.
137+
125138
impl<G> GasProfiler<G>
126139
where
127140
G: AptosGasMeter,
128141
{
142+
// Method to print the module_gas_usage hash table
143+
pub fn print_module_gas_usage(&self) {
144+
for (module_id, gas) in &self.module_gas_usage {
145+
println!("Module: {:?}, Gas Used: {:?}", module_id, gas);
146+
}
147+
}
148+
149+
fn is_intra_module_call(&self, module_id: &ModuleId) -> bool {
150+
if let Some(frame) = self.frames.last() {
151+
if let FrameName::Function { module_id: current_module_id, .. } = &frame.name {
152+
return current_module_id == module_id;
153+
}
154+
}
155+
false
156+
}
157+
158+
// Add a method to get the total gas usage for a module
159+
pub fn get_module_gas_usage(&self, module_id: &ModuleId) -> InternalGas {
160+
*self.module_gas_usage.get(module_id).unwrap_or(&InternalGas::zero())
161+
}
162+
163+
fn charge_call_with_metering(
164+
&mut self,
165+
module_id: &ModuleId,
166+
func_name: &str,
167+
args: impl ExactSizeIterator<Item = impl ValueView> + Clone,
168+
num_locals: NumArgs,
169+
) -> PartialVMResult<()> {
170+
let is_intra_module = self.is_intra_module_call(module_id);
171+
let base_cost = if is_intra_module {
172+
InternalGas::new(0)
173+
} else {
174+
InternalGas::new(20)
175+
};
176+
177+
let (cost, res) = self.delegate_charge(|base| {
178+
base.charge_call(module_id, func_name, args, num_locals)
179+
});
180+
let total_cost = cost + base_cost;
181+
182+
// if !is_intra_module {
183+
// print!("Inter module call\n");
184+
// print!("Old cost: {}\n", cost);
185+
// print!("New Cost: {}\n", cost+base_cost);
186+
// }
187+
// println!("Module ID: {:?}, Total Cost: {:?}", module_id, total_cost);
188+
189+
// Record gas usage for the current module
190+
*self.module_gas_usage.entry(module_id.clone()).or_insert(InternalGas::zero()) += total_cost;
191+
// Push the current gas cost onto the stack
192+
self.gas_cost_stack.push(self.base.balance_internal());
193+
self.record_bytecode(Opcodes::CALL, cost + base_cost);
194+
self.frames.push(CallFrame::new_function(
195+
module_id.clone(),
196+
Identifier::new(func_name).unwrap(),
197+
vec![],
198+
));
199+
200+
res
201+
}
202+
203+
fn charge_call_generic_with_metering(
204+
&mut self,
205+
module_id: &ModuleId,
206+
func_name: &str,
207+
ty_args: impl ExactSizeIterator<Item = impl TypeView> + Clone,
208+
args: impl ExactSizeIterator<Item = impl ValueView> + Clone,
209+
num_locals: NumArgs,
210+
) -> PartialVMResult<()> {
211+
let is_intra_module = self.is_intra_module_call(module_id);
212+
let base_cost = if is_intra_module {
213+
InternalGas::new(0)
214+
} else {
215+
InternalGas::new(20)
216+
};
217+
218+
let ty_tags = ty_args
219+
.clone()
220+
.map(|ty| ty.to_type_tag())
221+
.collect::<Vec<_>>();
222+
223+
let (cost, res) = self.delegate_charge(|base| {
224+
base.charge_call_generic(module_id, func_name, ty_args, args, num_locals)
225+
});
226+
227+
let total_cost = cost + base_cost;
228+
229+
if !is_intra_module {
230+
print!("Inter module call\n");
231+
print!("Old cost: {}\n", cost);
232+
print!("New Cost: {}\n", cost + base_cost);
233+
}
234+
// println!("Module ID: {:?}, Total Cost: {:?}", module_id, total_cost);
235+
// Record gas usage for the current module
236+
*self.module_gas_usage.entry(module_id.clone()).or_insert(InternalGas::zero()) += total_cost;
237+
// Push the current gas cost onto the stack
238+
self.gas_cost_stack.push(self.base.balance_internal());
239+
self.record_bytecode(Opcodes::CALL_GENERIC, cost + base_cost);
240+
self.frames.push(CallFrame::new_function(
241+
module_id.clone(),
242+
Identifier::new(func_name).unwrap(),
243+
ty_tags,
244+
));
245+
246+
res
247+
}
248+
129249
fn active_event_stream(&mut self) -> &mut Vec<ExecutionGasEvent> {
130250
&mut self.frames.last_mut().unwrap().events
131251
}
@@ -399,7 +519,16 @@ where
399519
if matches!(instr, SimpleInstruction::Ret) && self.frames.len() > 1 {
400520
let cur_frame = self.frames.pop().expect("frame must exist");
401521
let last_frame = self.frames.last_mut().expect("frame must exist");
402-
last_frame.events.push(ExecutionGasEvent::Call(cur_frame));
522+
last_frame.events.push(ExecutionGasEvent::Call(cur_frame.clone()));
523+
// Pop the gas cost from the stack and calculate the difference
524+
let start_gas = self.gas_cost_stack.pop().expect("stack must not be empty");
525+
let end_gas = self.base.balance_internal();
526+
let function_cost = start_gas.checked_sub(end_gas).expect("gas cost must be non-negative");
527+
528+
// Print the function name and cost
529+
if let FrameName::Function { name, .. } = &cur_frame.name {
530+
println!("Function: {}, Cost: {:?}", name, function_cost);
531+
}
403532
}
404533

405534
res
@@ -412,17 +541,7 @@ where
412541
args: impl ExactSizeIterator<Item = impl ValueView> + Clone,
413542
num_locals: NumArgs,
414543
) -> PartialVMResult<()> {
415-
let (cost, res) =
416-
self.delegate_charge(|base| base.charge_call(module_id, func_name, args, num_locals));
417-
418-
self.record_bytecode(Opcodes::CALL, cost);
419-
self.frames.push(CallFrame::new_function(
420-
module_id.clone(),
421-
Identifier::new(func_name).unwrap(),
422-
vec![],
423-
));
424-
425-
res
544+
self.charge_call_with_metering(module_id, func_name, args, num_locals)
426545
}
427546

428547
fn charge_call_generic(
@@ -433,23 +552,7 @@ where
433552
args: impl ExactSizeIterator<Item = impl ValueView> + Clone,
434553
num_locals: NumArgs,
435554
) -> PartialVMResult<()> {
436-
let ty_tags = ty_args
437-
.clone()
438-
.map(|ty| ty.to_type_tag())
439-
.collect::<Vec<_>>();
440-
441-
let (cost, res) = self.delegate_charge(|base| {
442-
base.charge_call_generic(module_id, func_name, ty_args, args, num_locals)
443-
});
444-
445-
self.record_bytecode(Opcodes::CALL_GENERIC, cost);
446-
self.frames.push(CallFrame::new_function(
447-
module_id.clone(),
448-
Identifier::new(func_name).unwrap(),
449-
ty_tags,
450-
));
451-
452-
res
555+
self.charge_call_generic_with_metering(module_id, func_name, ty_args, args, num_locals)
453556
}
454557

455558
fn charge_load_resource(
@@ -668,6 +771,8 @@ where
668771
G: AptosGasMeter,
669772
{
670773
pub fn finish(mut self) -> TransactionGasLog {
774+
// Print the module_gas_usage hash table
775+
self.print_module_gas_usage();
671776
while self.frames.len() > 1 {
672777
let cur = self.frames.pop().expect("frame must exist");
673778
let last = self.frames.last_mut().expect("frame must exist");

aptos-move/aptos-vm-logging/src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,10 @@ pub fn speculative_log(level: Level, context: &AdapterLogSchema, message: String
107107
};
108108
},
109109
None => {
110-
speculative_alert!(
111-
"Speculative state not initialized to log message = {}",
112-
message
113-
);
110+
// speculative_alert!(
111+
// "Speculative state not initialized to log message = {}",
112+
// message
113+
// );
114114
},
115115
};
116116
}

0 commit comments

Comments
 (0)